2013-07-14 81 views
4

我在Python中使用metaclasses,发现一些非常好奇的东西。我可以创建两个具有相同名称的类,但实际上它们是不同的对象。请参阅:在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

你能解释一下名字空间中的名字应该是唯一的吗? – User

+0

@使用名称空间中每个对象的名称(在本例中为'__main__')应该是唯一的。我认为'MyClass'是一个对象的名称,正如下面的答案所解释的那样,它不是。 – erickrf

回答

6

名称空间中的名称是唯一的,但这对您的情况没有任何影响。基本上有两个不同的东西:“名字”和__name__ s。 “名称”是名称空间中的变量。 A __name__只是一个类的属性,其值是“类调用自己”。

在上面的代码中,MyClass__name__AB是名称。 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 

刚好路过MyClasstype实际上并没有创建一个名为MyClass变量。正是这些实际的变量名是唯一的,而不是其名称的内部概念。

如果一个类是相同的类对象,则它与另一个类相同。即使它们具有相同的__name__属性,它们仍然可以是不同的对象。

+1

@erickrf:请注意[**类定义**](http://docs.python.org/2/reference/compound_stmts.html#class-definitions)文档中第一段的最后一句,它表示“类名称绑定到原始本地名称空间中的此类对象“。换句话说,可执行的'class'语句将创建的类对象分配给本地名称空间中的同名变量。当你通过调用'type()'来创建类时,它不会自动发生。 – martineau

5

该类的名称是类对象本身的属性。通常当你定义一个类时,你将它绑定到一个变量(带有类名),但类名仍然会存储在类对象本身中。

在你的情况,你正在做两个新的对象是不同的,但碰巧都是类,并具有相同的名称。而且它们不像正常类那样绑定到名称空间中的变量。

相关问题