Python:从字符串引用类?

时间:2009-04-09 16:29:50

标签: python

如何使用包含类名的字符串来引用类本身?
看到这个(不工作)例子......

class WrapperClass:
    def display_var(self):
        #FIXME: self.__class_name__.__name__ is a string
        print self.__class__.__name__.the_var

class SomeSubClass(WrapperClass):
    var = "abc"

class AnotherSubClass(WrapperClass):
    var = "def"

一条明显的错误信息:

>>> b = SomeSubClass()
>>> b.display_var()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 4, in display_var
AttributeError: 'str' object has no attribute 'the_var'
>>> 

谢谢!

4 个答案:

答案 0 :(得分:7)

  

如何使用包含类名的字符串来引用类本身?

类并不特殊,它们只是变量中包含的值。如果你说过:

class X(object): pass

在全局范围内,那么变量'X'将是对类对象的引用。

您可以使用'globals()'将当前脚本/模块的全局变量作为字典获取,所以:

classobj= globals()[self.__class__.__name__]
print classobj.var

locals()也可用于局部变量;在它们之间你不应该使用糟糕的eval()来访问变量。)

然而正如David所说,self.__class__已经已经 classobj,因此无需按名称从全局变量中获取它; self.__class__.var没问题。虽然真的:

print self.var

通常是简单的方法。类成员可以作为其实例的成员使用,只要该实例不会用其他内容覆盖该名称。

答案 1 :(得分:2)

根据您获取此字符串的位置,任何常规方法都可能不安全(一种方法是简单地使用eval(string)。最好的方法是定义一个dict映射名称到类:

class WrapperClass:
    def display_var(self):
        #FIXME: self.__class_name__.__name__ is a string
        print d[self.__class__.__name__].the_var

class SomeSubClass(WrapperClass):
    the_var = "abc"

class AnotherSubClass(WrapperClass):
    the_var = "def"

d = {'WrapperClass': WrapperClass, 'SomeSubClass': SomeSubClass, 'AnotherSubClass': AnotherSubClass}
AnotherSubClass().display_var()
# prints 'def'

答案 2 :(得分:1)

如果您拨打print self.__class__.var,您的示例就会有效。我认为没有必要使用这个名称。

答案 3 :(得分:0)

在某些情况下,只有一个类的名称,而没有对它的引用。 tkinter Entry小部件具有validate方法,该方法将小部件的名称而不是对其的引用返回给回调函数(%W参数)。如果您的窗口中包含多个输入字段,则为每个输入使用不同的回调函数是不方便的。在回调函数中将字符串名称转换为引用是将回调与validate事件的源关联的更有效方法。我会对德文的回答发表评论,但尚无声望可言。