给定一个字符串作为Python函数的用户输入,如果当前定义的命名空间中有一个具有该名称的类,则希望从中获得一个类对象。本质上,我想实现一个函数,它将产生这样的结果:

class Foo:
    pass

str_to_class("Foo")
==> <class __main__.Foo at 0x69ba0>

这有可能吗?


当前回答

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)

这可以准确地处理旧样式和新样式的类。

其他回答

在任意代码执行方面,或者不希望用户传递的名称,您可以有一个可接受的函数/类名称列表,如果输入与列表中的一个匹配,则对其进行计算。

PS:我知道....有点晚了…但这是为将来偶然发现这个的人准备的。

使用importlib最适合我。

import importlib

importlib.import_module('accounting.views') 

它使用字符串点表示法来表示你想导入的python模块。

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

警告:eval()可用于执行任意Python代码。永远不要对不受信任的字符串使用eval()。(请参阅Python的eval()对不受信任字符串的安全性?)

这似乎是最简单的。

>>> class Foo(object):
...     pass
... 
>>> eval("Foo")
<class '__main__.Foo'>