我正在玩Python中的元类,发现了一些非常好奇的东西。我可以创建两个具有相同名称的类,但实际上它们是不同的对象。参见:
>>> 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
我认为名称空间中的名称应该是唯一的。那不是吗?
答案 0 :(得分:7)
命名空间中的名称是唯一的,但这与您的情况无关。基本上有两个不同的东西:“名字”和__name__
。 “name”是命名空间中的变量。 __name__
只是一个类的属性,其值为“类自称的内容”。
在上面的代码中,MyClass
是__name__
,A
和B
是名称。 MyClass
不是__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
传递给type
实际上并不会创建名为MyClass
的变量。这些实际变量名称是唯一的,而不是类的内部名称概念。
如果类是同一个类对象,则该类与另一个类相同。即使它们具有相同的__name__
属性,它们仍然可以是不同的对象。
答案 1 :(得分:5)
类的名称是类对象本身的属性。通常在定义类时,将它绑定到变量(带有类名),但类名仍将存储在类对象本身中。
在你的情况下,你正在制作两个不同的新对象,但它们都是类,并且具有相同的名称。并且它们不像命名常规类那样绑定到命名空间中的变量。