7

私は Python でメタクラスをいじっていて、非常に興味深いものを見つけました。同じ名前の 2 つのクラスを作成できますが、それらは実際には異なるオブジェクトです。見る:

>>> def create_class(**data):
...     return type('MyClass', (object,), data)
... 
>>> A = create_class(x=1, y=2)
>>> B = create_class(x=1, y=2)
>>> A
<class '__main__.MyClass'>
>>> B
<class '__main__.MyClass'>
>>> A == B
False
>>> a = A()
>>> b = B()
>>> type(a)
<class '__main__.MyClass'>
>>> type(b)
<class '__main__.MyClass'>
>>> type(a) == type(b)
False

名前空間内の名前は一意であるべきだと思いました。では、そうではありませんか?

4

2 に答える 2

10

名前空間内の名前は一意ですが、ここでの状況には関係ありません。__name__基本的に、「名前」とsという 2 つの異なるものがあります。「名前」は名前空間内の変数です。A__name__は、値が「クラスがそれ自体を呼び出すもの」であるクラスの単なる属性です。

上記のコードでMyClassは、と__name__は名前です。 名前空間の名前ではありません。表示されている「クラス」はクラスの属性であり、名前空間内の実際の変数ではありません。通常、クラスは定義した名前と同じになりますが、呼び出してプログラムでクラスを作成した場合、名前空間内の任意の名前を介してアクセスできるとは限りませんが、必ずしもアクセスできるとは限りません。ABMyClass__main____main__.MyClass__name____name__type__name__

違いの簡単な例を次に示します。

>>> A = type('MyClass', (object,), {})
>>> MyClass
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    MyClass
NameError: name 'MyClass' is not defined

に渡すだけでは、実際には という変数は作成MyClassされません。一意なのは、これらの実際の変数名であり、クラスの名前の内部概念ではありません。typeMyClass

それらが同じクラスオブジェクトである場合、クラスは別のクラスと同じです。同じ__name__属性であっても、異なるオブジェクトである可能性があります。

于 2013-07-14T18:02:09.523 に答える
5

クラスの名前は、クラス オブジェクト自体の属性です。通常、クラスを定義するときは、それを (クラス名で) 変数にバインドしますが、クラス名は引き続きクラス オブジェクト自体の内部に格納されます。

あなたの場合、異なる 2 つの新しいオブジェクトを作成していますが、たまたま両方ともクラスであり、同じ名前を持っています。また、通常のクラスと同じように、名前空間内の変数にバインドされていません。

于 2013-07-14T17:59:47.080 に答える