概して、Pythonでは、すべてのオブジェクトは辞書に保存されます辞書-辞書全体に固有のキーを持つオブジェクトのリストがあります。
class A(): i=1; s='string'
print dir(A)
> ['__doc__', '__module__', 'i', 's']
このプロパティを使用すると、クラスやクラスインスタンスでさまざまなことを「取得」できます。 例:
class A(): v0=1
class B(A):
v1=2
def __init__(self):
self.v2 = 3
b=B()
print b.v2, b.v1, b.v0
> 3 2 1
Pythonがv2を取得しようとしたとき、すべてが明確です-インスタンスbの辞書から取得されます。 さらに興味深いことに、プロパティv1には要素bが含まれておらず、辞書Bが含まれています-Pythonがそこから取得しました。 そして最後に、要素v0を検索するとき、親BAのディクショナリを検索し、そこから取り出します。 プロパティv0がb内で決定される場合、その値はより高いレベルに上昇することなくそこから取得されることは明らかです。
def __init__(self):
print self
class A(): pass
setattr(A, '__init__', __init__)
a=A()
> <__main__.A instance at 0x009E9EB8>
この例では、__ init__関数をクラスAの制限に移動しました(他の名前で関数を移動できます。説明のために__init__を提供しています)。 クラス宣言は次と同等です:
class A():
def __init__(self):
print self
Pythonのクラスは、メタクラスのインスタンスです。 これは驚きです。なぜなら、インスタンスだけでなく、その場でクラスを定義できるようになったからです。
def __init__(self):
print self
B = type('B', (), {})
setattr(B, '__init__', __init__)
b = B()
> <__ main __。0x009E7CD0のBオブジェクト>
関数はクラスのインスタンスに対してのみ定義され、クラスA自体に対しては呼び出せないことに注意してください。 一方、この機会を追加することを妨げているのは何ですか。
def Omd(obj):
print obj
B = type('B', (), {})
setattr(B, 'c', classmethod(Omd))
setattr(B, 'o', Omd)
b = B()
bc(), bo()
> <クラス '__main __。B'>
> <__ main __。0x009E7D50のBオブジェクト>
本当に楽しいですか?! 最初の引数を出力する関数を特定しました。 次に、メタクラスに基づいてクラスを作成しました(
class A(type): pass
として標準的に定義できます)。 クラスの隣に、私たちのものが隠されている静的関数「c」と、クラスBのインスタンスからそれを呼び出す関数「o」を追加しました。最初にクラスが表示され、その後にインスタンスが表示されます。 これが彼らの愛です。