在Python中在所述类中创建类的静态实例

时间:2010-03-30 15:49:42

标签: 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中做同样的事情?

3 个答案:

答案 0 :(得分:12)

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

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

Python中的类是一个与任何其他类似的对象,您可以随时添加新变量。你不能在类中做到这一点,因为它当时没有定义(只有在正确解析了类的整个代码之后才会将它添加到符号表中)。

答案 1 :(得分:3)

虽然Aaron的答案是首选方式,但您也可以使用元类:

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

答案 2 :(得分: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")