web-dev-qa-db-ja.com

Pythonで「自己」を使用するのはいつですか?

Python(同じモジュール内))でメンバー関数を参照するときにselfを使用することになっていますか?

より一般的には、メソッドだけでなく変数にもselfを使用する必要があるのか​​疑問に思っていました。

29
Dark Templar

オスカルビは明示的ではないため、答えを追加します。

次の場合にselfを使用します。

  1. インスタンスメソッドの定義。インスタンスのメソッドを呼び出すときに、最初のパラメーターとして自動的に渡され、メソッドが呼び出されたインスタンスです。
  2. インスタンスメソッド内からclassまたはinstance属性を参照する。それを使用して、メソッドを呼び出すか、メソッドが呼び出されたインスタンスの名前(変数)にそのメソッド内からアクセスします。

あなたはしてはいけないselfを使用する

  1. 通常、インスタンスメソッドを呼び出します。 Oskarbiの例を使用すると、instance = MyClass()を実行すると、instance.my_method(some_var)ではなくinstance.my_method(self, some_var)として_MyClass.my_method_を呼び出します。
  2. クラス属性は、インスタンス定義メソッドoutsideから、ただしクラス定義内で参照します。
  3. staticmethod の中にいます。

これらは、自己を使用しない場合の単なる例です。 dosは、shouldを使用するときです。

29
agf

selfを使用して、他のインスタンスメソッドからインスタンス変数とメソッドを参照します。インスタンスメソッドの定義の最初のパラメーターとしてselfも配置します。

例:

class MyClass(object):

    my_var = None

    def my_method(self, my_var):
         self.my_var = my_var
         self.my_other_method()

    def my_other_method(self):
         # do something...
14
Oskarbi
  1. 名前selfについてnothing 'special'があります。これは、Pythonistasによって慣例により優先される名前であり、そのパラメーターに含まれるものが示されます。

  2. Pythonランタイムは、意図的にインスタンスを提供するかどうかにかかわらず、インスタンスのインスタンスメソッドを呼び出すと、 'self'値を渡します。これは通常、簡単に診断/理解されたエラーになります(関数は間違った数のパラメーターで呼び出されます)が、_*args_を使用すると、かなり奇妙な型エラーが発生する可能性があります。

  3. インスタンスのインスタンスメソッドを呼び出すと、パラメーターが暗黙的に渡されます。メソッドを呼び出すインスタンスが含まれています。したがって、関数呼び出しでselfに言及しないのは、(a)上記のように、それは意味をなさない(一般にスコープにselfがなく、 selfはキーワードでも特別な名前でも何でもありません); (b)使用するインスタンスを既に指定しています(_my_instance._を記述して)。

  4. もちろん、クラスからアクセスすることにより、インスタンスメソッドを明示的に呼び出すことができます。この場合、インスタンスを最初のパラメーターとして明示的に渡す必要があります。一般的に言って、あなたはこれをしたくありません。そして、あなたは特に最初のパラメータがこのように明示的に渡された何かである可能性を考慮したコードを書きたくない。これは、C++でif (this == null)をチェックするのと似ています。意味がない場合は、呼び出しコードはwrongで、合法でない場合は道徳的に(少なくともPythonでは、未定義の動作に問題はありませんが、それでも道徳的に間違っています。)

  5. インスタンスメソッド内では、selfはインスタンスを値として割り当てられたパラメーターなので、_self.whatever_を記述してインスタンスの属性にアクセスできます。他の「暗黙のthis」スタイル言語とは異なり、属性名はnot暗黙的に「スコープ内」です。

  6. selfには他のユースケースはありません。これもまた特別な名前ではなく、それが命名規則が扱う特定の目的の1つであるためです。別のモジュールから「変数」(実際には属性)にアクセスする必要がある場合は、モジュール名を使用します。現在のモジュールからアクセスしたい場合、接頭辞は必要ありません、またはそのことについて本当に可能です。 (まあ、あなたはcouldglobals()によって返されたdictで明示的に検索しますが、それをしないでください。)

4
Karl Knechtel

インスタンス変数およびメソッドの場合、いつでもselfを使用することが必須です。

3
lc2817