给定一个字符串作为Python函数的用户输入,如果当前定义的命名空间中有一个具有该名称的类,则希望从中获得一个类对象。本质上,我想实现一个函数,它将产生这样的结果:
class Foo:
pass
str_to_class("Foo")
==> <class __main__.Foo at 0x69ba0>
这有可能吗?
给定一个字符串作为Python函数的用户输入,如果当前定义的命名空间中有一个具有该名称的类,则希望从中获得一个类对象。本质上,我想实现一个函数,它将产生这样的结果:
class Foo:
pass
str_to_class("Foo")
==> <class __main__.Foo at 0x69ba0>
这有可能吗?
当前回答
是的,你可以做到。假设你的类存在于全局命名空间中,如下所示:
import types
class Foo:
pass
def str_to_class(s):
if s in globals() and isinstance(globals()[s], types.ClassType):
return globals()[s]
return None
str_to_class('Foo')
==> <class __main__.Foo at 0x340808cc>
其他回答
import sys
import types
def str_to_class(field):
try:
identifier = getattr(sys.modules[__name__], field)
except AttributeError:
raise NameError("%s doesn't exist." % field)
if isinstance(identifier, (types.ClassType, types.TypeType)):
return identifier
raise TypeError("%s is not a class." % field)
这可以准确地处理旧样式和新样式的类。
这是可行的:
import sys
def str_to_class(classname):
return getattr(sys.modules[__name__], classname)
警告:eval()可用于执行任意Python代码。永远不要对不受信任的字符串使用eval()。(请参阅Python的eval()对不受信任字符串的安全性?)
这似乎是最简单的。
>>> class Foo(object):
... pass
...
>>> eval("Foo")
<class '__main__.Foo'>
您需要类Baz,它位于模块foo.bar中。在Python 2.7中, 你想要使用importlib.import_module(),因为这将使过渡到Python 3更容易:
import importlib
def class_for_name(module_name, class_name):
# load the module, will raise ImportError if module cannot be loaded
m = importlib.import_module(module_name)
# get the class, will raise AttributeError if class cannot be found
c = getattr(m, class_name)
return c
使用Python < 2.7:
def class_for_name(module_name, class_name):
# load the module, will raise ImportError if module cannot be loaded
m = __import__(module_name, globals(), locals(), class_name)
# get the class, will raise AttributeError if class cannot be found
c = getattr(m, class_name)
return c
Use:
loaded_class = class_for_name('foo.bar', 'Baz')
是的,你可以做到。假设你的类存在于全局命名空间中,如下所示:
import types
class Foo:
pass
def str_to_class(s):
if s in globals() and isinstance(globals()[s], types.ClassType):
return globals()[s]
return None
str_to_class('Foo')
==> <class __main__.Foo at 0x340808cc>