【问题标题】:Instantiate a Python class from a name [duplicate]从名称实例化 Python 类 [重复]
【发布时间】:2010-02-09 02:21:04
【问题描述】:

所以我有一组类和一个带有类名的字符串。如何根据该字符串实例化一个类?

class foo:
  def __init__(self, left, right):
     self.left = left
     self.right = right

str = "foo"
x = Init(str, A, B)

我希望 x 成为类 foo 的实例化。

【问题讨论】:

标签: python


【解决方案1】:

在你的情况下,你可以使用类似的东西:

get_class = lambda x: globals()[x]
c = get_class("foo")

而且从模块中获取类更容易:

import somemodule
getattr(somemodule, "SomeClass")

【讨论】:

    【解决方案2】:

    如果你知道所涉及的命名空间,你可以直接使用它——例如,如果所有的类都在模块zap中,那么字典vars(zap)就是那个命名空间;如果它们都在当前模块中,globals() 可能是获取该字典的最便捷方式。

    如果这些类并非都在同一个命名空间中,那么正如@Ignacio 所建议的那样,构建一个“人工”命名空间(以类名作为键、类对象作为值的专用字典)可能是最简单的方法。

    【讨论】:

      【解决方案3】:
      classdict = {'foo': foo}
      
      x = classdict['foo'](A, B)
      

      【讨论】:

      • 如何使用反射来做到这一点?
      • 可以使用getattr(),但这可能会使您面临安全问题。使用类装饰器可以让您自动枚举类,但这些仅存在于较新版本的 Python 中。
      • 你会如何使用装饰器?它会附加到可实例化类的列表中吗?我必须遍历这个列表来选择正确的类来实例化?
      • @UtkarshSinha: ... 不,它会在classdict 中添加一个条目。
      【解决方案4】:
      classname = "Foo"
      foo = vars()[classname](Bar, 0, 4)
      

      或许

      def mkinst(cls, *args, **kwargs):
          try:
              return globals()[cls](*args, **kwargs)
          except:
              raise NameError("Class %s is not defined" % cls)
      
      x = mkinst("Foo", bar, 0, 4, disc="bust")
      y = mkinst("Bar", foo, batman="robin")
      

      关于sn-p的杂记:

      *args**kwargs 是 Python 中的特殊参数,它们相应地表示“非关键字参数的数组”和“关键字参数的字典”。

      PEP-8(官方 Python 风格指南)建议对类变量使用 cls

      vars() 返回本地范围内定义的变量字典。

      globals() 返回当前存在于本地范围之外的环境中的变量的字典。

      【讨论】:

        【解决方案5】:

        试试这个

        cls = __import__('cls_name')
        

        这 - http://effbot.org/zone/import-confusion.htm 可能有帮助

        【讨论】:

          【解决方案6】:

          您也可以考虑使用元类:

          Cls = type('foo', (), foo.__dict__)
          x = Cls(A, B)
          

          但它创建了另一个类似的类。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-01-13
            • 2014-05-25
            • 1970-01-01
            • 2012-04-08
            • 1970-01-01
            相关资源
            最近更新 更多