web-dev-qa-db-ja.com

python 'self'変数を初心者に説明する

私はOOP専門用語と概念。オブジェクトとは何か、そしてそのオブジェクトにはメソッドがあることを概念的に知っています。Pythonではクラスはオブジェクトであるということさえ理解しています!それが何を意味するのか分からないだけです。

私は現在、Pythonの私の理解を照らすと思ういくつかの詳細な答えを理解しようとしています:

  1. 「yield」キーワードはPythonで何をしますか?
  2. Pythonのメタクラスとは

最初の回答では、作成者は次のコードを例として使用します。

_>>> class Bank(): # let's create a bank, building ATMs
...    crisis = False
...    def create_atm(self) :
...        while not self.crisis :
...            yield "$100"
_

selfが指しているものをすぐに理解しません。これは間違いなくクラスを理解していないことの症状であり、これについてはいつか取り組んでいきます。明確にするために、

_>>> def func():
...   for i in range(3):
...     print i
_

iはリストrange(3)内の項目を指していることを理解しています。これは関数内にあるため、グローバルではありません。しかし、selfは「指す」ものは何ですか?

33
jrhorn424

最初に、クラスとオブジェクトに関する混乱を解消しようとします。次のコードブロックを見てみましょう。

>>> class Bank(): # let's create a bank, building ATMs
...    crisis = False
...    def create_atm(self) :
...        while not self.crisis :
...            yield "$100"

そこのコメントは少し欺de的です。上記のコードは銀行を「作成」しません。銀行とは何かを定義します。銀行とは、crisisというプロパティと、create_atmという関数を持つものです。それは上記のコードが言うことです。

次に、実際に銀行を作成しましょう。

>>> x = Bank()

そこで、xは銀行になりました。 xには、プロパティcrisisと関数create_atmがあります。 pythonでx.create_atm();を呼び出すことはBank.create_atm(x);を呼び出すことと同じであるため、selfxを参照します。yという別のバンクを追加すると、y.create_atm()関数yxを参照しているため、selfの値ではなく、yの危機の値を確認してください。

selfは単なる命名規則ですが、それに固執することは非常に良いことです。上記のコードは次のものと同等であることを指摘する価値があります。

>>> class Bank(): # let's create a bank, building ATMs
...    crisis = False
...    def create_atm(thisbank) :
...        while not thisbank.crisis :
...            yield "$100"
92
Paulpro

obj.method(arg1, arg2)呼び出し構文をmethod(obj, arg1, arg2)を呼び出すための純粋に構文的なシュガーと考えるのに役立ちます(methodobjの型を介して検索されることを除きます) 、およびグローバルではありません)。

このように表示すると、objが関数の最初の引数になります。これは従来、パラメーターリストではselfという名前です。 (実際には、別の名前を付けることができ、コードは正常に機能しますが、他のPythonコーダーはあなたに眉をひそめます。)

18

self」はインスタンスオブジェクトです自動的に呼び出されたときにクラスインスタンスのメソッドに渡され、それを呼び出したインスタンスを識別します。 「self」は、メソッド内からオブジェクトの他の属性またはメソッドにアクセスするために使用されます。 (メソッドは基本的にクラスに属する単なる関数です)

self」は、使用可能なインスタンスがある場合にメソッドを呼び出すときに使用する必要はありません。

メソッド内から「some_attribute」属性にアクセスする:

class MyClass(object):
    some_attribute = "hello"

    def some_method(self, some_string):
        print self.some_attribute + " " + some_string

既存のインスタンスから「some_attribute」属性にアクセスする:

>>> # create the instance
>>> inst = MyClass()
>>>
>>> # accessing the attribute
>>> inst.some_attribute
"hello"
>>> 
>>> # calling the instance's method
>>> inst.some_method("world") # In addition to "world", inst is *automatically* passed here as the first argument to "some_method".
hello world
>>> 

Selfがインスタンスと同じであることを示すための小さなコードを次に示します。

>>> class MyClass(object):
>>>     def whoami(self, inst):
>>>         print self is inst
>>>
>>> local_instance = MyClass()

>>> local_instance.whoami(local_instance)
True

他の人が述べたように、慣例により「self」という名前が付けられていますが、任意の名前を付けることができます。

12
monkut

selfは、Bankの現在のインスタンスを指します。新しいBankを作成し、その上でcreate_atmを呼び出すと、selfがPythonによって暗黙的に渡され、作成した銀行を参照します。

5
recursive

selfが指しているものをすぐに理解しません。これは間違いなくクラスを理解していないことの症状であり、これについてはいつか取り組んでいきます。

selfは、関数に渡される引数です。 Pythonでは、この最初の引数は暗黙的にメソッドが呼び出されたオブジェクトです。言い換えると:

_class Bar(object):
    def someMethod(self):
        return self.field

bar = Bar()

bar.someMethod()
Bar.someMethod(bar)
_

これらの最後の2行には、同等の動作があります。 (barBarのサブクラスのオブジェクトを参照しない限り、someMethod()は異なる関数オブジェクトを参照する可能性があります。)

「特別な」最初の引数に名前を付けることができることに注意してください必要なもの-selfはメソッドの単なる規則です。

iはリストrange(3)内の項目を指していることを理解しています。これは関数内にあるため、グローバルではありません。しかし、selfは「指す」ものは何ですか?

名前selfは、その関数のコンテキストには存在しません。使用しようとすると、NameErrorが発生します。


トランスクリプトの例:

_>>> class Bar(object):
...     def someMethod(self):
...         return self.field
...
>>> bar = Bar()
>>> bar.field = "foo"
>>> bar.someMethod()
'foo'
>>> Bar.someMethod(bar)
'foo'
>>> def fn(i):
...     return self
...
>>> fn(0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in fn
NameError: global name 'self' is not defined
_
5
cdhowie

(慣例により)「自己」が存在する理由は、PythonランタイムがObject.Method(Param1、Param2)という形式の呼び出しを検出すると、パラメーター(Object、Param1 、Param2)。したがって、その最初のパラメーターを「自己」と呼ぶと、誰もがあなたが話していることを知ることができます。

これをしなければならない理由は、別の質問の主題です。

メタクラスに関しては、めったに使用されないものです。ご覧ください: http://python-history.blogspot.com/2009/04/metaclasses-and-extension-classes-aka.html 、元の作者であり、現在の慈悲深い独裁者Life of Pythonはこれが何であり、どのようになったのかを説明しています。

2
psr

1つのRubyistの視点(Rubyは私の最初のプログラミング言語なので、私が使用しようとしている単純化された、潜在的に間違った抽象化については謝罪します)

私が知る限り、たとえばドット演算子:

_os.path
_

ospath()に最初の変数として「見えないように」渡されるようなものです

_os.path_が本当にこれであるかのように:

_path(os)
_

デイジーチェーンがあった場合、私はこれを想像します:

_os.path.filename
_

実際にはこのようなものになります*:

_filename(path(os))
_

ここに攻撃的な部分があります自己変数では、クラスメソッドを許可するだけです(ルビイストの観点からpython 'インスタンスメソッド'はクラスメソッドのように見えます。 ..)慣例によりselfと呼ばれる最初の変数(上記の「卑劣な」ドットメソッドを介して)に渡されるインスタンスを取得することにより、インスタンスメソッドとして機能する。

_c = ClassName()
c.methodname
_

しかし、クラス自体:

_ClassName.methodname
_

インスタンスではなくクラスが渡されます。

OK、覚えておくべき重要なことは、___init___メソッドが「マジック」と呼ばれることです。したがって、新しいインスタンスの生成に何が渡されるかについて心配する必要はありません。正直なところ、おそらくnilです。

2
boulder_ruby

selfは、クラスのインスタンスを指します。

1
MRAB