なぜ「自己」が必要なのですか。インスタンス変数を参照するPythonで?


13

Java、Ruby、Haskell、Pythonなどの多くの言語でプログラミングを行ってきました。作業しているプロジェクトが異なるため、1日に多くの言語を切り替える必要があります。今、問題はself、Pythonの関数定義の最初のパラメーターが同じオブジェクトのメソッドを呼び出すことと同じであるため、書くのを忘れることが多いことです。

そうは言っても、このPythonのアプローチには非常に驚かされます。基本的には、JavaやRubyなどの言語では、現在のオブジェクトの変数を自動的に参照することで簡単にできるように、もっと入力する必要があります。

私の質問は、なぜこれがself必要なのですか?それは純粋にスタイルの選択ですか、それともPythonでselfJavaとC ++で省略できる方法を省略できないのthisですか?



1
@gnatは今や長所だけであり、数日から私を悩ませている良い質問です。投票でそれを殺さないでください。
vivek

2
この質問は、stackoverflow.com / questions / 2709821 /…で完全に網羅されています。
デビッドアルノ

私の理解では、最初の引数として構造体へのポインターを渡すCスタイルに基づいているということです。
ダンノ

回答:


23

1)selfメソッドシグネチャの明示的なパラメーターとして必要なのはなぜですか?

メソッドは関数でfoo.bar(baz)あり、単なる構文糖衣であるためbar(foo, baz)です。クラスは、値の一部が関数である単なる辞書です。(コンストラクターも単なる関数であるため、Pythonは必要ありません。new)Pythonは、オブジェクトがより単純なコンポーネントから構築されていることを明示していると言えます。これは「明示的は暗黙的よりも優れている」という哲学に基づいています。

対照的に、Javaのオブジェクトは本当に魔法であり、言語のより単純なコンポーネントに減らすことはできません。Java(少なくともJava 8まで)では、関数は常にオブジェクトが所有するメソッドであり、この所有権は言語の静的な性質のために変更できません。したがって、何をthis参照するかについてあいまいさはないため、暗黙的に定義することは理にかなっています。

JavaScriptは、thisJavaのような暗黙の言語の例ですが、Pythonのように関数はオブジェクトとは別に存在できます。これは、異なるコンテキストで関数が渡され、呼び出されるときに参照するものについて多くの混乱をもたらしthisます。多くthisの場合、関数の固有のプロパティを参照する必要がありますが、実際には関数の呼び出し方法によって純粋に決定されます。私が持つと信じてthisPythonでのような明示的なパラメータは、これははるかに少ない混乱になるだろうと。

明示的selfパラメーターのその他の利点:

  • デコレータは、他の機能をラップする単なる機能です。メソッドは単なる関数であるため、デコレーターはメソッドでも同じように機能します。暗黙的な自己がある場合、デコレーターはメソッドに対して透過的に機能しません。

  • クラスメソッドと静的メソッドはインスタンスパラメータを取りません。クラスメソッドは、最初の引数としてクラスを取ります(通常、と呼ばれますcls)。明示的なselfor clsパラメーターは、何が起こっているのか、メソッドで何にアクセスできるのかをより明確にします。

2)インスタンス変数を常に修飾する必要があるのはなぜself.ですか?

Javaでは、メンバー変数の前に「this.」を付ける必要はありませんが、Pythonではself.常に「」が必要です。その理由は、Pythonには変数を宣言するための明示的な構文がないためx = 7、新しいローカル変数を宣言するかメンバー変数に割り当てるかを判断する方法がないためです。指定self.すると、このあいまいさが解決されます。


暗黙的なメンバー変数参照(self.Javaのようななし)は基本的にスコープ規則と互換性がありません。そこで明示的にする必要がある場合、パラメーターについて暗黙的であることはあまり意味がありません。
Jan Hudec

@JanHudec:いいですね、ポイント。答えに追加しました。
ジャックB

6

クロスサイトの複製でAFAIKが実際には触れられていないという単純な理由があります。Pythonは手続き型言語として始まりました。これも手続き言語であるABCに基づいていました。

オブジェクト指向は後で追加されましたが、追加されたとき、Guido van RossumはPythonの設計をシンプルに保つために、可能な限り最小限の機能を追加したいと考えていました。Pythonには既にdictsと関数があったので、オブジェクトが単純dictにスロットになり、クラスが単純dictに関数になることができるのに、言語にまったく新しいものを追加するのはなぜですか?メソッドは、1つの顕著な引数を閉じる部分的に適用された関数として解釈できます。そして、それがまさにPythonでのメソッドの実装方法です。そうではありません。これらは、特別な引数を受け取る単なる関数です。


Pythonはオブジェクト指向をサポートし、最初のリリースバージョンからクラスと継承を持っていると思います。少なくともこれはウィキペディアが私に言っていることです。しかし、最初に言語を設計する際のvan Rossumsのプロセスは、あなたが説明したとおりだったかもしれません。
ジャックB


リンクをありがとう、これは本当に興味深い読書です。
ジャックB

2

上記の回答に基づいて、このトピックに関するグイド自身のとりとめを読んで、私の結論を以下に示します。

大きなアイデア

関数はPythonの重要なビルディングブロック(または、唯一のブロック)であり、実際、関数を使用してOOPをエミュレートするようなものです。

したがって、クラスは関数の辞書に過ぎないため、実行時に任意の関数を任意のクラスにアタッチできます。基本的には、実行時に関数を投げる必要があるためです。MonkeyPatchingのような処理を実行できます。ここで、selfパラメトリック多態性をサポートするパラメーター。


1
回答が質の高い回答である場合、自己回答の質問が推奨されます。 ここでの回答を他の回答と比較すると、なぜこれを追加する必要があると感じたのか疑問に思っています。他の答えはより深く入り、あなたの答えがすることよりも詳細を追加します。

1
@ GlenH7答えは私の参考のためだけでした。なぜなら、私は来て、みんなの答えを何度も何度も読むことができないからです。品質に関して、少しでも情報が誤解を招く場合は教えてください。とにかく、私は通常、2〜3日待って答えを受け入れます。
vivek

ダウン投票は安価な通貨になりつつあり、ここの誰もがその意味を知らずに両手でそれを使っています。誰かがここに来た場合、この答えが間違っていると思われるダウン投票を見ることに気付きますか?
vivek
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.