私はOOP専門用語と概念。オブジェクトとは何か、そしてそのオブジェクトにはメソッドがあることを概念的に知っています。Pythonではクラスはオブジェクトであるということさえ理解しています!それが何を意味するのか分からないだけです。
私は現在、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
は「指す」ものは何ですか?
最初に、クラスとオブジェクトに関する混乱を解消しようとします。次のコードブロックを見てみましょう。
>>> 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);
を呼び出すことと同じであるため、self
はx
を参照します。y
という別のバンクを追加すると、y.create_atm()
関数y
はx
を参照しているため、self
の値ではなく、y
の危機の値を確認してください。
self
は単なる命名規則ですが、それに固執することは非常に良いことです。上記のコードは次のものと同等であることを指摘する価値があります。
>>> class Bank(): # let's create a bank, building ATMs
... crisis = False
... def create_atm(thisbank) :
... while not thisbank.crisis :
... yield "$100"
obj.method(arg1, arg2)
呼び出し構文をmethod(obj, arg1, arg2)
を呼び出すための純粋に構文的なシュガーと考えるのに役立ちます(method
はobj
の型を介して検索されることを除きます) 、およびグローバルではありません)。
このように表示すると、obj
が関数の最初の引数になります。これは従来、パラメーターリストではself
という名前です。 (実際には、別の名前を付けることができ、コードは正常に機能しますが、他のPythonコーダーはあなたに眉をひそめます。)
「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」という名前が付けられていますが、任意の名前を付けることができます。
self
は、Bank
の現在のインスタンスを指します。新しいBank
を作成し、その上でcreate_atm
を呼び出すと、self
がPythonによって暗黙的に渡され、作成した銀行を参照します。
self
が指しているものをすぐに理解しません。これは間違いなくクラスを理解していないことの症状であり、これについてはいつか取り組んでいきます。
self
は、関数に渡される引数です。 Pythonでは、この最初の引数は暗黙的にメソッドが呼び出されたオブジェクトです。言い換えると:
_class Bar(object):
def someMethod(self):
return self.field
bar = Bar()
bar.someMethod()
Bar.someMethod(bar)
_
これらの最後の2行には、同等の動作があります。 (bar
がBar
のサブクラスのオブジェクトを参照しない限り、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
_
(慣例により)「自己」が存在する理由は、PythonランタイムがObject.Method(Param1、Param2)という形式の呼び出しを検出すると、パラメーター(Object、Param1 、Param2)。したがって、その最初のパラメーターを「自己」と呼ぶと、誰もがあなたが話していることを知ることができます。
これをしなければならない理由は、別の質問の主題です。
メタクラスに関しては、めったに使用されないものです。ご覧ください: http://python-history.blogspot.com/2009/04/metaclasses-and-extension-classes-aka.html 、元の作者であり、現在の慈悲深い独裁者Life of Pythonはこれが何であり、どのようになったのかを説明しています。
1つのRubyistの視点(Rubyは私の最初のプログラミング言語なので、私が使用しようとしている単純化された、潜在的に間違った抽象化については謝罪します)
私が知る限り、たとえばドット演算子:
_os.path
_
os
がpath()
に最初の変数として「見えないように」渡されるようなものです
_os.path
_が本当にこれであるかのように:
_path(os)
_
デイジーチェーンがあった場合、私はこれを想像します:
_os.path.filename
_
実際にはこのようなものになります*:
_filename(path(os))
_
ここに攻撃的な部分があります自己変数では、クラスメソッドを許可するだけです(ルビイストの観点からpython 'インスタンスメソッド'はクラスメソッドのように見えます。 ..)慣例によりself
と呼ばれる最初の変数(上記の「卑劣な」ドットメソッドを介して)に渡されるインスタンスを取得することにより、インスタンスメソッドとして機能する。
_c = ClassName()
c.methodname
_
しかし、クラス自体:
_ClassName.methodname
_
インスタンスではなくクラスが渡されます。
OK、覚えておくべき重要なことは、___init__
_メソッドが「マジック」と呼ばれることです。したがって、新しいインスタンスの生成に何が渡されるかについて心配する必要はありません。正直なところ、おそらくnil
です。
self
は、クラスのインスタンスを指します。