python 有相当于 Java Class.forName() 的吗? [英] Does python have an equivalent to Java Class.forName()?

查看:33
本文介绍了python 有相当于 Java Class.forName() 的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<小时>

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

解决方案

python 中的反射比 Java 中的反射要容易得多,也灵活得多.

我推荐阅读这个教程

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

尽管有一点建议:当您使用 Python 时,不要尝试以 Java 风格进行编程.

如果你能解释你想要做什么,也许我们可以帮助你找到一种更 Pythonic 的方法.

这是一个可以执行您想要的操作的函数:

def get_class( kls ):零件 = kls.split('.')模块 = ".".join(parts[:-1])m = __import__( 模块 )对于零件 [1:] 中的补偿:m = getattr(m, comp)返回米

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

这是一个用法示例:

<预><代码>>>>D = get_class("日期时间.日期时间")>>>D<输入'日期时间.日期时间'>>>>D.now()datetime.datetime(2009, 1, 17, 2, 15, 58, 883000)>>>a = D( 2010, 4, 22 )>>>一种datetime.datetime(2010, 4, 22, 0, 0)>>>

这是如何运作的?

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

m = __import__( 模块 )

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

例如,如果您的类位于 foo.baz 模块中,则 m 将是模块 foo
我们可以使用 getattr( m, 'baz' )

轻松获得对 foo.baz 的引用

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

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

m = __import__( "foo.baz.bar" ) #m 是包 foom = getattr( m, "baz" ) #m 是包 bazm = getattr( m, "bar" ) #m 是模块栏m = getattr( m, "Model" ) #m 是类模型

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

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

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

a = m() #实例化类的新实例b = m( arg1, arg2 ) # 将参数传递给构造函数

I have the need to take a string argument and create an object of the class named in that string in Python. In Java, I would use Class.forName().newInstance(). Is there an equivalent in Python?


Thanks for the responses. To answer those who want to know what I'm doing: I want to use a command line argument as the class name, and instantiate it. I'm actually programming in Jython and instantiating Java classes, hence the Java-ness of the question. getattr() works great. Thanks much.

解决方案

Reflection in python is a lot easier and far more flexible than it is in Java.

I recommend reading this tutorial

There's no direct function (that I know of) which takes a fully qualified class name and returns the class, however you have all the pieces needed to build that, and you can connect them together.

One bit of advice though: don't try to program in Java style when you're in python.

If you can explain what is it that you're trying to do, maybe we can help you find a more pythonic way of doing it.

Here's a function that does what you want:

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

You can use the return value of this function as if it were the class itself.

Here's a usage example:

>>> 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)
>>> 

How does that work?

We're using __import__ to import the module that holds the class, which required that we first extract the module name from the fully qualified name. Then we import the module:

m = __import__( module )

In this case, m will only refer to the top level module,

For example, if your class lives in foo.baz module, then m will be the module foo
We can easily obtain a reference to foo.baz using getattr( m, 'baz' )

To get from the top level module to the class, have to recursively use gettatr on the parts of the class name

Say for example, if you class name is foo.baz.bar.Model then we do this:

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

This is what's happening in this loop:

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

At the end of the loop, m will be a reference to the class. This means that m is actually the class itslef, you can do for instance:

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

这篇关于python 有相当于 Java Class.forName() 的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆