2010-03-30 156 views
8

如果我在这里遇到了术语错误的道歉,我无法想象这个特定的习惯用法会被调用。在Python中的类中创建一个类的静态实例

我一直在尝试创建一个静态声明自身内部实例的Python 3类 - 有点像枚举可以工作。下面是我写的代码的简化版本:

class Test: 
    A = Test("A") 
    B = Test("B") 

    def __init__(self, value): 
     self.value = value 

    def __str__(self): 
     return "Test: " + self.value 

print(str(Test.A)) 
print(str(Test.B)) 

写这本,我上线2(A = Test("A"))异常。我假设第3行也会出错,如果它已经做到了这一点。使用__class__而不是Test给出了相同的错误。

File "<stdin>", line 1, in <module> 
    File "<stdin>", line 2, in Test 
NameError: name 'Test' is not defined 

有什么办法在Python的静态上下文中引用当前类?我可以在类之外或者在一个单独的类中声明这些特定的变量,但为了清楚起见,如果我能够帮助它,我宁愿不要。

为了更好地说明什么,我试图做的,这里是一个Java同样的例子:

public class Test { 
    private static final Test A = new Test("A"); 
    private static final Test B = new Test("B"); 

    private final String value; 

    public Test(String value) { 
     this.value = value; 
    } 

    public String toString() { 
     return "Test: " + value; 
    } 

    public static void main(String[] args) { 
     System.out.println(A); 
     System.out.println(B); 
    } 
} 

这个工作你所期望的:它打印:

Test: A 
Test: B 

我该怎么办Python中的一样东西?

回答

9

后您定义的类,只需添加以下两行:

Test.A = Test("A") 
Test.B = Test("B") 

在Python类是像任何其他的对象,你可以随时增加新的变数。你不能在类内部完成它,因为它当时没有定义(只有在类的整个代码已被正确解析后,它才会被添加到符号表中)。

+0

当然 - 不能相信我没有看到这一点。非常感谢您的帮助。 – 2010-03-30 15:58:07

2

在Python中,class块不仅仅是一个声明;它在运行时被执行来构建类。类中的每个def都会构建一个函数并将该名称绑定到该类的名称空间中。出于这个原因,您不能直接在类块中直接执行A = MyClass(),因为MyClass()在类块关闭之前没有完全定义。以下是如何做到这一点:

class Test: 
    def __init__(self, value): 
     self.value = value 

    def __str__(self): 
     return "Test: " + self.value 

Test.A = Test("A") 
Test.B = Test("B") 
2

虽然阿龙的回答是首选的方式,您还可以使用元类:

>>> class TestMeta(type): 
... def __init__(cls, name, bases, dct): 
... cls.A = cls() 
... cls.B = cls() 
... 
>>> class Test: 
... __metaclass__ = TestMeta 
... 
>>> Test 
<class __main__.Test at 0x7f70f8799770> 
>>> Test.A 
<__main__.Test object at 0x7f70f86f2e10> 
>>> Test.B 
<__main__.Test object at 0x7f70f86f2e90> 
>>> 
+0

很酷。元类是我以前没有玩过的东西。我必须在某个时候尝试一下。 – 2010-03-30 16:09:15

相关问题