質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

4回答

794閲覧

selfの使い方がわからない

yyjfou

総合スコア35

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/05/02 14:14

selfの理解ができません。
本に

class Dog: def bark(self,dog_name): self.dog_model = dog_model dog_a = Dog() #1 dog_a.bark(”わんわん")

というコードが載っていましたが、「このselfは生成されたオブジェクト自身の事です」とありました。

生成されたオブジェクト自身が何を指しているのか分かりません。#1の部分のことでしょうか?

また#1だとしても、なぜ

def bark(self,dog_name): self.dog_model = dog_model

のところで、引数にselfを持たせないといけないのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

生成されたオブジェクト自身

大雑把に#1の部分としてしまっても良いですが、厳密にはDog()という式を評価した結果得られる値のことですね。それをdog_aという変数に束縛しているのがその行のやっていることです。

Pythonのオブジェクト指向では、クラスを呼び出すと新たなインスタンスが生成されて返される仕組みになっています。

で、その本の「selfは生成されたオブジェクト自身」という説明は誰が読んでもよくわからないと思いますが、要するに

python

1dog_a.bark("わんわん") 2

python

1Dog.bark(dog_a, "わんわん") 2

と基本的に等価の呼び出しになるということを述べており、端的にまとめると「インスタンスメソッドの呼び出し時にはインスタンスが第一引数に渡される」という説明で良いと思います。

余談ですが、selfという名前でなくても機能します。

引数にselfを持たせないといけないのでしょうか?

逆に、ないと困るのは。

なんらかの方法でインスタンスにアクセスできないと、オブジェクト指向プログラミングができません。メソッドの場合は第一引数からオブジェクト自身が渡されるように変換される、というのは、唯一の方法ではないにせよ、ちゃんと機能する仕組みです。

#まあしかし、オブジェクト指向はPythonの最初期からあったとしても、Guidoが先に仕組みを思いついたのは名前空間と関数オブジェクトだったのだろうな……という実装ではありますね。

投稿2021/05/03 08:15

編集2021/05/03 08:19
hayataka2049

総合スコア30935

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yyjfou

2021/05/05 08:36

ありがとうございます。勉強になりました!
guest

0

生成されたオブジェクト自身が何を指しているのか分かりません。#1の部分のことでしょうか?

定義されたクラスのインスタンスのことです。
x.bark('abc')などと書いたときのxがselfに渡されます。
dog_a の中身はDogクラスのインスタンスですので、dog_a.bark()ではselfにdog_a の中身が渡されます。

なぜ、引数にselfを持たせないといけないのでしょうか?

もっとも簡単な説明は、グイド・ヴァンロッサムさんがそう決めたからです。グイド・ヴァンロッサムさんはPython言語の優しい終身の独裁者(BDFL)ですので、その決定が仕様(specification)となります。

公式な説明は、公式ドキュメントのデザインと歴史 FAQの中の、なぜメソッドの定義や呼び出しにおいて 'self' を明示しなければならないのですか?に書かれています。

この問題には、多くの人が疑問を持ったり異議を唱えたりするらしく、グイド・ヴァンロッサムさんがブログで説明しています。

Why explicit self has to stay

日本語訳は以下です。

和訳 なぜPythonのメソッド引数に明示的にselfと書くのか

私個人は、「クラスを動的に書き換えることができる」ということが出来るのを実験的にやってみて知っていて、邪道かもしれないけれども便利だなと思っていました。実はロッサムさん自身がそれを意図して仕様として決めているということをこの文章で知って、さすがだなと思いました。

投稿2021/05/02 16:13

ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yyjfou

2021/05/05 08:36

ありがとうございます。勉強になりました!
guest

0

「このselfは生成されたオブジェクト自身の事です」とありました。

これは語弊があります。
def barkの中で出てくるselfは、dog_a.bark(”わんわん")barkを呼び出した時のピリオドの直前の値(この場合は変数dog_aの中身)を表します。

まあ、「生成されたオブジェクト」であることには違いないですが、「生成されたオブジェクト」は、数行のサンプルプログラムでも無い限り、プログラム中に何個も出てくるので、そのうちのどれかというと、上記の通りです。

なぜ~~のところで、引数にselfを持たせないといけないのでしょうか?

訂正:
失礼しました。当初からオブジェクト指向機能があったようですね。
(C++でなく)Cでオブジェクト指向開発をする際には、レシーバーを引数で渡すので、それと同じようなものかとばかり思っていました。

これは、Pythonが出来た時にはオブジェクト指向の機能が無くて、あとから追加した際に、もともとあった関数の機能を使ったため、呼び出し元から値を受け取る仕組みが引数しか無く、レシーバー(メソッド名の前のピリオドの前のオブジェクト)を関数の引数として書く必要があったと言うことだと思います。

当初設計時点からオブジェクト指向機能のあったプログラミング言語だと、引数にレシーバーを書かなくて良いのが普通でしょう。

投稿2021/05/02 14:29

編集2021/05/02 14:43
otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yyjfou

2021/05/05 08:36

ありがとうございます。勉強になりました!
guest

0

生成されたオブジェクト自身が何を指しているのか分かりません。#1の部分のことでしょうか?

はい

のところで、引数にselfを持たせないといけないのでしょうか?

selfを常に書くなら省略できるのでは、ということだと思いますがこれはpythonの設計思想なので
そういった思想で作っているから、としか言えないと思います。

参考URL:
なんで self を書かないといけないの?

投稿2021/05/02 14:23

jamjam3

総合スコア165

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yyjfou

2021/05/05 08:37

ありがとうございます。勉強になりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問