你可以使用一个string来实例化一个类在Python中?

我正在使用一个生成器模式来分离一堆不同的configuration可能性。 基本上,我有一堆名为ID(类似于ID12345)的类。 这些全部从基础构build器类inheritance。 在我的脚本中,我需要为每个类(大约50)每次运行这个应用程序实例化一个实例。 所以,我试图看看,而不是做这样的事情:

ProcessDirector = ProcessDirector() ID12345 = ID12345() ID01234 = ID01234() ProcessDirector.construct(ID12345) ProcessDirector.construct(ID01234) ID12345.run() ID01234.run() 

我可以做这样的事情(我知道这是行不通的):

 IDS = ["ID12345", "ID01234"] ProcessDirector = ProcessDirector() for id in IDS: builder = id() #some how instantiate class from string ProcessDirector.construct(builder) builder.run() 

这样,当我需要在将来添加一个新的ID时,我所要做的就是将ID添加到IDS列表中,而不是在整个代码中join新的ID。

编辑

看起来像根据数据来自哪里有一些不同的意见。 这些ID被input到其他人无法访问的文件中。 我没有从命令行读取string,我希望将来能够在添加新的ID时尽可能less地进行修改。

不完全确定这是你想要的,但它似乎是一个更python的方式来实例化一串在string中列出的类:

 class idClasses: class ID12345:pass class ID01234:pass # could also be: import idClasses class ProcessDirector: def __init__(self): self.allClasses = [] def construct(self, builderName): targetClass = getattr(idClasses, builderName) instance = targetClass() self.allClasses.append(instance) IDS = ["ID12345", "ID01234"] director = ProcessDirector() for id in IDS: director.construct(id) print director.allClasses # [<__main__.ID12345 instance at 0x7d850>, <__main__.ID01234 instance at 0x7d918>] 

如果你想避免一个eval(),你可以这样做:

 id = "1234asdf" constructor = globals()[id] instance = constructor() 

只要该类在您的当前范围内定义(或导入)。

如果可以帮助,请不要使用eval() 。 Python有很多更好的select(派遣字典, getattr()等),您不应该使用称为eval()的安全漏洞。

最简单的方法是创build一个字典。

 class A(object): pass class B(object): pass namedclass = {'ID12345': A, 'ID2': A, 'B': B, 'AnotherB': B, 'ID01234': B} 

然后使用它(你的代码示例):

 IDS = ["ID12345", "ID01234"] ProcessDirector = ProcessDirector() for id in IDS: builder = namedclass[id]() ProcessDirector.construct(builder) builder.run() 

有一些东西从你的问题缺less,所以我不得不猜测在省略的东西。 随意编辑您的问题,以纠正遗漏。

 class ProcessDirector( object ): # does something class ID12345( SomeKindOfProcess ): pass class ID001234( SomeKindOfProcess ): pass idList= [ID12345, ID01234] theProcessDirector = ProcessDirector() for id in idList: builder = id() #Instantiate an object from the class object theProcessDirector.construct(builder) builder.run() 

这工作非常好。 它没有从string实例化 – 在实践中你并不经常需要这个。 有时候,但很less。 更常见的是,您需要一个您想要实例对象的类对象的列表。

如果你真的从命令行中获得你的类名,那么你可以进行下面的小改动。

 validClasses = [ ID12345, ID01234 ] validMap = dict( ( (c.__name__, c) for c in validClasses ) ) nameStrings = [ "ID12345", "ID01234" ] # from your command-line idList= [ validMap[s] for s in nameStrings ] 

其他一切都保持不变。

[另外,如果可能的话,尝试使用小写字母来启动实例variables名称。 以大写字母开头的名称通常是类名。]

编辑

删除eval 。 尽pipeeval()绝对不是安全漏洞。 如果有人专门授权访问恶意用户,Eval(以及execexecfile )只是一个问题。