2013-08-21 54 views
2

我注意到python不会让你添加一个类的实例作为类定义的静态成员。自己类型的python静态字段

>>> class Foo: 
...  A = Foo() 
... 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 2, in Foo 
NameError: name 'Foo' is not defined 

但以下两种工作:

>>> class Foo: 
...  pass 
... 
>>> class Foo: 
...  A = Foo() 
... 
>>> Foo.A 
<__main__.Foo instance at 0x100854440> 

>>> class Foo: 
...  pass 
... 
>>> Foo.A = Foo() 
>>> 
>>> Foo.A 
<__main__.Foo instance at 0x105843440> 

我无法找到任何启​​发的代码示例或解释。为什么python以不同的方式处理第一个案例? A在以后两个案例中的每一个案例中都有哪些?

回答

6

您的第一个示例不起作用,因为您尚未创建类Foo。你正在这样做(因此NameError

你的第二个例子工作,因为你有一个叫Foo()类。你重写它,但你仍然保留它的副本。看看这个:

>>> class Foo: 
...  def __init__(self): 
...    print 'hi' 
... 
>>> class Foo: 
...  A = Foo() 
... 
hi 
>>> Foo.A 
<__main__.Foo instance at 0x101019950> 
>>> Foo.A.__init__ 
<bound method Foo.__init__ of <__main__.Foo instance at 0x101019950>> 

A是一个属性,它具有您所覆盖的类的值。

至于你的第三个例子,你只是简单地将一个类的属性作为这个类的一个实例。

3

编辑:看this question在Python中自引用类的例子。)

我认为这将拼出来:

>>> class Test: 
...  a = 3 
... 
>>> class Test: 
...  m = Test() 
... 
>>> 
>>> t = Test() 
>>> t.m 
<__main__.Test object at 0x01E73690> 
>>> t.a 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'Test' object has no attribute 'a' 
>>> t.m.a 
3 

令人惊讶的是,这为您提供了两种不同类型的同名。但我想第一堂课是“迷失”的,只能通过第二堂。

1

创建一个类首先评估它的主体,然后创建一个类对象。

所以

class Foo: 
    A = Foo() # here class Foo doesn't exist yet 
# but here it exists. 

Here是如何创建一个类对象的作品。)

你的第二个示例创建一个类,然后使用相同的名称,而不是与在第一个创建另一个类任何方式。因此,

>>> isinstance(Foo.A, Foo) 
False 

你的第三个例子在它的创建后使用它来扩展它。

所以,

>>> isinstance(Foo.A, Foo) 
True 

为什么蟒蛇不同的方式对待第一种情况?

因为标识符还不存在。

在以后两个案例中的每一个案例中,哪一个在哪里?

这是什么意思,它到底在哪里?

0

在类定义时间,类本身还不存在,执行缩进块的内容并解析任何名称并调用函数。此时,类的名称,基类和包含要存储在类中的名称和值的字典将传递给元类,该类创建实际的类并将其绑定到指定的名称。您可以在类初始化时通过使用metaclass创建类的“静态”实例。这将执行类定义中的代码,将名称,基础和词典传递给元类函数,该函数创建类并在其中创建类的实例,然后将其绑定到名称。试想一下:

def staticInstanceMetaclass(name, bases, dict_): 
    ret=type(name, bases, dict_) 
    for i in dict_: 
     if dict_[i]=='STATICINSTANCE': 
     setattr(ret,i,ret()) 
    return ret 

class ClassWithStaticInstance(object): 
    __metaclass__=staticInstanceMetaclass 
    myStaticInstance='STATICINSTANCE' 
    myFirstVar=5 

print ClassWithStaticInstance.myStaticInstance 

注意,在上面的例子中,dict_包含

{'myStaticInstance': 'STATICINSTANCE', '__module__': '__main__', '__metaclass__': <function staticInstanceMetaclass at 0x1213668>, 'myFirstVar': 5} 

当你到预先在Python中创建静态情况下,这是我们所密切。有关元类的更多信息,以及如何影响类的创建,请参阅this问题。

相关问题