7

我在 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

我认为命名空间中的名称应该是唯一的。不是这样吗?

4

2 回答 2

10

命名空间中的名称是唯一的,但这与您在这里的情况没有任何关系。基本上有两种不同的东西:“名称”和__name__s。“名称”是命名空间中的变量。A__name__只是一个类的属性,其值是“类自称的东西”。

在上面的代码中,MyClassis a __name__and Aand Bare names。 MyClass不是__main__命名空间中的名称。__main__.MyClass您看到的“类”只是类的__name__属性,而不是命名空间中的实际变量。通常该类的__name__名称与您定义它时使用的名称相同,但如果您type像以前那样通过调用以编程方式创建一个类,它仍然具有 a__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

只是传递MyClasstype实际上并没有创建一个名为MyClass. 正是这些实际的变量名称是唯一的,而不是类的内部名称概念。

A class is the same as another class if they are the same class object. Even if they have the same __name__ attribute, they can still be different objects.

于 2013-07-14T18:02:09.523 回答
5

类的名称是类对象本身的一个属性。通常,当您定义一个类时,您将它绑定到一个变量(使用类名),但类名仍将存储在类对象本身中。

在您的情况下,您正在创建两个不同的新对象,但它们恰好都是类,并且具有相同的名称。并且它们不像普通类那样绑定到命名空间中的变量。

于 2013-07-14T17:59:47.080 回答