python 是否具有与 Java Class.forName() 等效的功能?

新手上路,请多包涵

我需要接受一个字符串参数并在 Python 中创建一个以该字符串命名的类的对象。在 Java 中,我会使用 Class.forName().newInstance() 。 Python 中是否有等效项?


感谢您的回复。回答那些想知道我在做什么的人:我想使用命令行参数作为类名,并将其实例化。我实际上是在用 Jython 编程并实例化 Java 类,因此问题的 Java 特性。 getattr() 效果很好。非常感谢。

原文由 Jason 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 426
2 个回答

Python 中的反射比 Java 中的反射简单得多,也灵活得多。

我推荐阅读本 教程(在 archive.org 上)

没有直接函数(据我所知)采用完全限定的类名并返回该类,但是您拥有构建它所需的所有部分,并且可以将它们连接在一起。

不过有一点建议:当您使用 Python 时,不要尝试以 Java 风格编程。

如果您可以解释您要尝试做什么,也许我们可以帮助您找到一种更符合 Python 风格的方法。

这是一个可以执行您想要的操作的功能:

 def get_class( kls ):
    parts = kls.split('.')
    module = ".".join(parts[:-1])
    m = __import__( module )
    for comp in parts[1:]:
        m = getattr(m, comp)
    return m

您可以像使用类本身一样使用此函数的返回值。

这是一个用法示例:

 >>> D = get_class("datetime.datetime")
>>> D
<type 'datetime.datetime'>
>>> D.now()
datetime.datetime(2009, 1, 17, 2, 15, 58, 883000)
>>> a = D( 2010, 4, 22 )
>>> a
datetime.datetime(2010, 4, 22, 0, 0)
>>>

这是如何运作的?

我们正在使用 __import__ 导入包含该类的模块,这要求我们首先从完全限定名称中提取模块名称。然后我们导入模块:

 m = __import__( module )

在这种情况下, m 将只引用顶层模块,

例如,如果您的课程位于 foo.baz 模块中,那么 m 将是模块 foo

我们可以使用 getattr( m, 'baz' ) 轻松获得对 foo.baz 的引用 —

要从顶层模块到类,必须在类名的部分递归使用 gettatr

例如,如果您的类名是 foo.baz.bar.Model 那么我们这样做:

 m = __import__( "foo.baz.bar" ) #m is package foo
m = getattr( m, "baz" ) #m is package baz
m = getattr( m, "bar" ) #m is module bar
m = getattr( m, "Model" ) #m is class Model

这就是这个循环中发生的事情:

 for comp in parts[1:]:
    m = getattr(m, comp)

在循环结束时, m 将是对该类的引用。这意味着 m 实际上是 itslef 类,你可以这样做:

 a = m() #instantiate a new instance of the class
b = m( arg1, arg2 ) # pass arguments to the constructor



原文由 hasen 发布,翻译遵循 CC BY-SA 4.0 许可协议

假设该类在您的范围内:

 globals()['classname'](args, to, constructor)

否则:

 getattr(someModule, 'classname')(args, to, constructor)

编辑:请注意,您不能将“foo.bar”之类的名称提供给 getattr。您需要将其拆分。并从左到右对每块调用 getattr()。这将处理:

 module, rest = 'foo.bar.baz'.split('.', 1)
fooBar = reduce(lambda a, b: getattr(a, b), rest.split('.'), globals()[module])
someVar = fooBar(args, to, constructor)

原文由 Serafina Brocious 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题