名前が同じ場合、pythonはクラス属性、インスタンス属性、およびメソッドをどのように区別しますか?
_class Exam(object):
test = "class var"
def __init__(self, n):
self.test = n
def test(self):
print "method : ",self.test
test_o = Exam("Fine")
print dir(test_o)
print Exam.test
print test_o.test
test_o.test()
_
出力:
_['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'test']
<unbound method load.test>
Fine
Traceback (most recent call last):
File "example.py", line 32, in <module>
test_o.test()
TypeError: 'str' object is not callable
_
電話のかけ方
Exam.test
_-> _<unbound method load.test>
_出力はメソッドを示しますtest_o.test
_-> _"Fine"
_test_o.test()
-> _TypeError: 'str' object is not callable
_クラス属性には、クラスからアクセスできます。
YourClass.clsattribute
またはインスタンスを介して(インスタンスがクラス属性を上書きしていない場合):
instance.clsattribute
述べられているように、メソッド 彼の答えのecatmurによる は記述子であり、クラス属性として設定されます。
インスタンスを介してメソッドにアクセスする場合、インスタンスはself
パラメーターとして記述子に渡されます。クラスからメソッドを呼び出す場合は、最初の引数としてインスタンスを明示的に渡す必要があります。したがって、これらは同等です。
instance.method()
MyClass.method(instance)
インスタンス属性とメソッドに同じ名前を使用すると、メソッドはインスタンスを介して非表示になりますが、メソッドはクラスを介して引き続き使用できます。
#python3
>>> class C:
... def __init__(self):
... self.a = 1
... def a(self):
... print('hello')
...
>>> C.a
<function a at 0x7f2c46ce3c88>
>>> instance = C()
>>> instance.a
1
>>> C.a(instance)
hello
結論:インスタンスの属性とメソッドに同じ名前を付けないでください。意味のある名前を付けることでこれを回避します。メソッドはアクションなので、私は通常、動詞や文を使用します。属性はデータであるため、名詞/形容詞を使用します。これにより、メソッドと属性の両方に同じ名前を使用することを回避できます。
メソッドが完全にオーバーライドするため、メソッドと同じ名前のクラス属性を持つことはできないことに注意してください(最終的に、メソッドは呼び出し可能なクラス属性であり、クラスのインスタンスを最初の属性として自動的に受け取ります) 。
あなたは書ける
_Exam.test(test_o)
_
または
_Exam.test.__get__(test_o)()
_
後者の場合、メソッドが descriptors であるという事実を使用して、_<unbound method load.test>
_をバインドされたメソッドに変換するため、単一の角かっこで呼び出すことができます。
test_o.test()
と書くと、Pythonは、メソッドを呼び出そうとしていることを認識しません。インストールされている関数または呼び出し可能オブジェクトを呼び出そうとしている可能性があります。オブジェクト上でインスタンスデータメンバーとして検索します。代わりに、最初にオブジェクト上で、次にそのクラス上で属性test
を検索しますが、属性はオブジェクト上に存在するため、クラス上のメソッドを非表示にします。
クラスのメンバー
_test = "class var"
_
メソッドtest
によって上書きされるため、アクセスできません(実際にはどこにも存在しません)。 class
ステートメント が実行されると、その名前空間はメタクラスに渡される前にdictに収集され、後の名前が前の名前をオーバーライドします。
電話のかけ方
クラス属性、_Exam.test
_
def test(self)
を実行すると、名前test
がクラスのメソッドにバインドされ、_"class var"
_への参照が失われるため、これはできません。
インスタンス属性_
test_o.test
_-> "Fine"
あなたはすでにそれをしました。
メソッド
test_o.test()
_self.test = n
_を実行すると、名前test
がインスタンス内のオブジェクトn
参照にバインドされ、インスタンス内のメソッドへの参照が失われるため、そのように呼び出すことはできません。 。
しかし、他の回答で指摘されているように、クラスのメソッドを呼び出して、インスタンスをそれに渡すことができます:Exam.test(test_o)
メソッドをクラスメソッドとして呼び出し、インスタンスをそれに渡すことができます。
Exam.test(test_o)
または、Exam
を使用したくない場合:
type(test_o).test(test_o)