オブジェクト
Pythonのすべてのデータはオブジェクトです。 各オブジェクトには、2つの特別な属性__class__および__dict__があります。
- __class__-インスタンスがオブジェクトであるクラスまたはタイプを定義します。 型(またはオブジェクトのクラス)がその動作を決定します。 組み込みのものを含むすべてのオブジェクトがそれを持っています。 タイプとクラスは同じものに対する異なる名前です。 x .__ class__ <==>タイプ(x)。
- __dict__は、内部名前空間へのアクセスを提供する辞書です。ほとんどすべてのオブジェクトに含まれていますが、多くの組み込み型にはありません。
>>> def foo (): pass
...
>>> foo . __class__
<type 'function'>
>>> foo . __dict__
{}
>>> ( 42 ) . __dict__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__dict__'
>>> ( 42 ) . __class__
<type 'int'>
>>> class A ( object ):
... qux = 'A'
... def __init__ ( self , name):
... self . name = name
... def foo ( self ):
... print 'foo'
...
>>> a = A( 'a' )
Aには__dict__と__class__もあります:
>>> a . __dict__ {'name': 'a'}
>>> a . __class__
<class '__main__.A'>
>>> type (a)
<class '__main__.A'>
>>> a . __class__ is type (a)
True
クラスとタイプはまったく同じです。
>>> a . __class__ is type (a) is A
True
a .__ dict__は、内部(またはオブジェクト固有の)属性(この場合は 'name')を含む辞書です。 .__ class__クラス(タイプ)。
また、たとえば、クラスメソッドでは、self.foo = barの割り当てはself .__ dict __ ['foo'] = barとほぼ同じであるか、同様の呼び出しになります。
クラスメソッド、記述子、クラス変数、プロパティ、__ dict__オブジェクト内のクラスの静的メソッドはありません。これらはすべて__class__属性のクラスを使用して動的に定義され、オブジェクト自体ではなくオブジェクトのクラス(タイプ)に固有です。
例。 オブジェクトaのクラスを再定義します。
>>> class B ( object ):
... qux = 'B'
... def __init__ ( self ):
... self . name = 'B object'
... def bar ( self ):
... print 'bar'
...
>>> a . __dict__
{'name': 'a'}
>>> a . foo()
foo
>>> a . __class__
<class '__main__.A'>
>>> a . __class__ = B
>>> a . __class__
<class '__main__.B'>
変更点を確認します。
a.nameの値は同じままです。 クラスを変更するときに__init__が呼び出されませんでした。
>>> a . __dict__
{'name': 'a'}
「過去の」クラスAのクラス変数とメソッドへのアクセスが失われました。
>>> a . foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'B' object has no attribute 'foo'
そして、クラスBアクセスのクラス変数とメソッドは次のとおりです。
>>> a . bar()
bar
>>> a . qux
'B'
オブジェクト属性の操作:インストール、削除、および検索は、組み込み関数settattr、delattr、getattrの呼び出しと同等です。
ax = 1 <==> setattr(a、 'x'、1)
del ax <==> delattr(a、 'x')
ax <==> getattr(a、 'x')
setattrとdelattrはオブジェクト自体(より正確には、.__ dict__)のみに影響し、変更し、オブジェクトのクラスは変更しないことを理解する必要があります。
qux-クラス変数、つまり それはオブジェクトBではなくクラスBに「属しています」。
>>> a . qux
'B'
>>> a . __dict__
{'name': 'a'}
この属性を削除しようとすると、エラーが発生します。 delattrは、.__ dict__から属性を削除しようとします。
>>> delattr (a, 'qux' )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: qux
>>> del a . qux
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: qux
>>> a . qux
'B'
>>>
さらに、属性を変更(設定)しようとすると、setattrはこの特定のオブジェクトに固有の__dict__にそれを配置します。
>>> b = B()
>>> b . qux
'B'
>>> a . qux = 'myB'
>>> a . qux
'myB'
>>> a . __dict__
{'qux': 'myB', 'name': 'a'}
>>> b . qux
'B'
>>>
まあ、__ dict__オブジェクトには 'qux'があるため、delattrを使用して削除できます。
>>> del a . qux
削除後、a.quxはクラス変数の値を返します。
>>> a . qux
'B'
>>> a . __dict__
{'name': 'a'}
だから:
- オブジェクトのクラスは特別な属性__class__の値であり、変更できます。 (公式文書には保証はないと書かれていますが、実際には可能です)
- ほとんどすべてのオブジェクトには独自の名前空間(属性)、アクセス(常に完全ではない)があり、これは特別な属性__dict__を使用して実行されます
- クラスは、実際には、クラスメソッド、記述子、マジックメソッド、クラス変数など、__ dict__にない属性の検索にのみ影響します。
オブジェクトとクラス
クラスはオブジェクトであり、特別な属性__class__と__dict__も持っています。
>>> class A ( object ):
... pass
...
クラスには型typeがあります。
>>> A . __class__
<type 'type'>
真の__dict__クラスには辞書がありません
>>> A . __dict__
<dictproxy object at 0x1111e88>
ただし、__ dict__は、メソッド、記述子、変数、プロパティなどを格納する内部名前空間へのアクセスを担当します。
>>> dict (A . __dict__)
{'__module__': '__main__', 'qux': 'A', '__dict__': <attribute '__dict__' of 'A' objects>, 'foo': <function foo at 0x7f7797a25c08>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
>>> A . __dict__ . keys()
['__module__', 'qux', '__dict__', 'foo', '__weakref__', '__doc__']<
クラスには、__ class__および__dict__に加えて、いくつかの特別な属性があります。__bases__-直接の親のリスト、__ name__-クラスの名前。 [1]
クラスは、型インターフェースを実装する通常のオブジェクトのある種の拡張と考えることができます。 すべてのクラス(または型)のセットは、すべてのオブジェクトのセットに属します。つまり、そのサブセットです。 つまり、クラスはオブジェクトですが、すべてのオブジェクトがクラスではありません。 通常のオブジェクトをクラスではないオブジェクトと呼ぶことに同意します。
少し後でよく理解されるようになる小さなデモ。
クラスはオブジェクトです。
>>> class A ( object ):
... pass
...
>>> isinstance (A, object )
True
数字もオブジェクトです。
>>> isinstance ( 42 , object )
True
クラスはクラス(つまり、タイプ)です。
>>> isinstance (A, type )
True
ただし、この番号はクラス(タイプ)ではありません。 (タイプとは後で説明します)
>>> isinstance ( 42 , type )
False
>>>
まあ、aも普通のオブジェクトです。
>>> a = A()
>>> isinstance (a, A)
True
>>> isinstance (a, object )
True
>>> isinstance (a, type )
False
Aには、直接の親クラスが1つだけあります-オブジェクトです。
>>> A . __bases__
(<type 'object'>,)
いくつかの特別なパラメーターも変更できます。
>>> A . __name__
'A'
>>> A . __name__ = 'B'
>>> A
<class '__main__.B'>
getattrを使用して、クラス属性にアクセスします。
>>> A . qux
'A'
>>> A . foo
<unbound method A.foo>
>>>
通常のオブジェクトの属性を検索する
最初の近似では、検索アルゴリズムは次のようになります:最初にオブジェクトの__dict__で検索され、次にオブジェクトのクラス(__class__を使用して決定される)の__dict__辞書と基本クラスの__dict__を再帰順に検索します。
例。
>>> class A ( object ):
... qux = 'A'
... def __init__ ( self , name):
... self . name = name
... def foo ( self ):
... print 'foo'
...
>>> a = A()
>>> b = A()
なぜなら 通常のオブジェクトaおよびbでは、__ dict__に 'qux'属性はありません。そのタイプ(クラス)の内部ディクショナリ__dict__で検索が続行され、__ dict__親ディクショナリに従って特定の順序で:
>>> b . qux
'A'
>>> A . qux
'A'
クラスAのqux属性を変更します。それに応じて、クラスA-aおよびbのインスタンスを返す値を変更する必要があります。
>>> A . qux = 'B'
>>> a . qux
'B'
>>> b . qux
'B'
>>>
同様に、実行時に、クラスにメソッドを追加できます。
>>> A . quux = lambda self : 'i have quux method'
>>> A . __dict__[ 'quux' ]
<function <lambda> at 0x7f7797a25b90>
>>> A . quux
<unbound method A.<lambda>>
そして、インスタンスへのアクセスが表示されます:
>>> a . quux()
'i have quux method'
他のオブジェクトと同様に、クラス属性(クラス変数quxなど)を削除できます。
>>> del A . qux
彼女は__dict__から引退します
>>> A . __dict__[ 'qux' ]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'qux'
また、インスタンスへのアクセスは失われます。
>>> a . qux
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'qux'
>>>
クラスは通常のオブジェクトとほとんど同じ属性検索を行いますが、違いがあります。検索は独自の__dict__辞書から始まり、特定のアルゴリズム、および__class__のクラスによってスーパークラスの__dict__辞書(__bases__に格納されています)を検索し、彼のスーパークラス。 (これについては後で詳しく説明します)。
リンク集
- Pythonで型とクラスを統合することは、新しいクラスで何を、どのように、そしてなぜを説明するメインドキュメントです。
- 型をクラスのように見えるようにする -古いクラスと新しいクラスの違いを説明するPEP 252。
- 組み込み関数 -すべての組み込み関数の操作の詳細な説明。
- データモデル -Pythonデータモデルの詳細な説明。
- Pythonタイプとオブジェクト -写真付きの簡単な例を使用したPythonオブジェクトモデルの説明。
注釈
[1]簡単にするために、__ module__と__doc__を忘れましょう。 クラス属性の完全なリストはドキュメントにあります。
続きを読む
Pythonパート2オブジェクトシステムに関する注意
Pythonオブジェクトシステムに関するパート3