python是否有与Java Class.forName()等价的函数?

2024-05-18 08:19:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要一个string参数,并在Python中创建一个在该字符串中命名的类的对象。在Java中,我将使用Class.forName().newInstance()。在Python中有等价物吗?


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


Tags: 对象实例字符串命令行参数string编程jython
3条回答

假设该类在您的范围内:

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

否则:

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

编辑:注意,不能给getattr起一个像“foo.bar”这样的名字。你得把它分开。然后从左到右调用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)

python中的反射比Java中的反射简单得多,灵活性也更高。

我建议你读这个tutorial

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

不过,有一点建议是:在使用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实际上是它的lef类,您可以执行以下操作:

a = m() #instantiate a new instance of the class    
b = m( arg1, arg2 ) # pass arguments to the constructor
def import_class_from_string(path):
    from importlib import import_module
    module_path, _, class_name = path.rpartition('.')
    mod = import_module(module_path)
    klass = getattr(mod, class_name)
    return klass

用法

In [59]: raise import_class_from_string('google.appengine.runtime.apiproxy_errors.DeadlineExceededError')()
---------------------------------------------------------------------------
DeadlineExceededError                     Traceback (most recent call last)
<ipython-input-59-b4e59d809b2f> in <module>()
----> 1 raise import_class_from_string('google.appengine.runtime.apiproxy_errors.DeadlineExceededError')()

DeadlineExceededError: 

相关问题 更多 >