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ページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答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総合スコア30935
0
生成されたオブジェクト自身が何を指しているのか分かりません。#1の部分のことでしょうか?
定義されたクラスのインスタンスのことです。
x.bark('abc')などと書いたときのxがselfに渡されます。
dog_a の中身はDogクラスのインスタンスですので、dog_a.bark()ではselfにdog_a の中身が渡されます。
なぜ、引数にselfを持たせないといけないのでしょうか?
もっとも簡単な説明は、グイド・ヴァンロッサムさんがそう決めたからです。グイド・ヴァンロッサムさんはPython言語の優しい終身の独裁者(BDFL)ですので、その決定が仕様(specification)となります。
公式な説明は、公式ドキュメントのデザインと歴史 FAQの中の、なぜメソッドの定義や呼び出しにおいて 'self' を明示しなければならないのですか?に書かれています。
この問題には、多くの人が疑問を持ったり異議を唱えたりするらしく、グイド・ヴァンロッサムさんがブログで説明しています。
日本語訳は以下です。
和訳 なぜPythonのメソッド引数に明示的にselfと書くのか
私個人は、「クラスを動的に書き換えることができる」ということが出来るのを実験的にやってみて知っていて、邪道かもしれないけれども便利だなと思っていました。実はロッサムさん自身がそれを意図して仕様として決めているということをこの文章で知って、さすがだなと思いました。
投稿2021/05/02 16:13
総合スコア24670
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
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総合スコア85901
0
生成されたオブジェクト自身が何を指しているのか分かりません。#1の部分のことでしょうか?
はい
のところで、引数にselfを持たせないといけないのでしょうか?
selfを常に書くなら省略できるのでは、ということだと思いますがこれはpythonの設計思想なので
そういった思想で作っているから、としか言えないと思います。
参考URL:
なんで self を書かないといけないの?
投稿2021/05/02 14:23
総合スコア165
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/05/05 08:36