【问题标题】:Python: Reference to a class from a string?Python:从字符串中引用类?
【发布时间】:2020-03-17 12:12:33
【问题描述】:

如何使用包含类名的字符串来引用类本身?
请参阅此(不工作)示例...

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() 回溯(最近一次通话最后): 文件“”,第 1 行,在 文件“”,第 4 行,在 display_var 中 AttributeError:“str”对象没有属性“the_var” >>>

谢谢!

【问题讨论】:

    标签: python


    【解决方案1】:

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

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

    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
    

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

    【讨论】:

    • hmmm:“变量‘X’将是一个引用”不准确。标识符“X”是类对象本身,可以在任何使用常量的地方使用。
    • 确实如此。我试图用笨拙的英语描述的是,虽然 X 是类对象,但它实际上只是一个参考;如果您将其他内容分配给“X”,那么它将不再是。重要的一点是,在 Python 中,“X”这个名字并没有变得特别;它只是另一个变量。
    【解决方案2】:

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

    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'
    

    【讨论】:

      【解决方案3】:

      如果您调用print self.__class__.var,您的示例将起作用。我认为没有必要使用这个名字。

      【讨论】:

      • 貌似没有,他知不知道怎么会问?
      【解决方案4】:

      存在这样一种情况,即有一个类的名称,但没有对它的引用。 tkinter Entry 小部件有一个 validate 方法,该方法返回回调函数(%W 参数)小部件的名称,而不是对其的引用。如果您有一个带有一组条目字段的窗口,则为每个条目使用不同的回调函数是不方便的。将字符串名称转换为回调函数中的引用是将回调关联到 validate 事件源的更有效方法。我会评论德文的回答,但还没有声誉点来制作 cmets。

      【讨论】:

        猜你喜欢
        • 2023-02-24
        • 1970-01-01
        • 2013-08-23
        • 1970-01-01
        • 1970-01-01
        • 2017-04-18
        • 2011-06-08
        • 2015-04-23
        • 1970-01-01
        相关资源
        最近更新 更多