sco*_*ttm 37 python reflection design-patterns
我正在使用构建器模式来分离一堆不同的配置可能性.基本上,我有一堆名为ID的类(类似于ID12345).这些都继承自基础构建器类.在我的脚本中,每次运行此应用程序时,我都需要为每个类(大约50个)实例化一个实例.所以,我试图看看是否代替做这样的事情:
ProcessDirector = ProcessDirector()
ID12345 = ID12345()
ID01234 = ID01234()
ProcessDirector.construct(ID12345)
ProcessDirector.construct(ID01234)
ID12345.run()
ID01234.run()
Run Code Online (Sandbox Code Playgroud)
我可以做这样的事情(我知道这不起作用):
IDS = ["ID12345", "ID01234"]
ProcessDirector = ProcessDirector()
for id in IDS:
builder = id() #some how instantiate class from string
ProcessDirector.construct(builder)
builder.run()
Run Code Online (Sandbox Code Playgroud)
这样,当我需要在将来添加一个新的时,我所要做的就是将ID添加到IDS列表中,而不是在整个代码中添加新的ID.
看起来根据数据的来源,有一些不同的意见.这些ID输入到其他人无法访问的文件中.我不是从命令行读取字符串,并且我希望将来在添加新ID时能够进行少量更改.
Gol*_*Boy 59
如果你想避免使用eval(),你可以这样做:
id = "1234asdf"
constructor = globals()[id]
instance = constructor()
Run Code Online (Sandbox Code Playgroud)
前提是该类在当前范围内定义(或导入).
dbr*_*dbr 17
不确定这是你想要的,但它似乎是一种更加Pythonic的方式来实例化字符串中列出的一堆类:
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>]
Run Code Online (Sandbox Code Playgroud)
eval()如果你能提供帮助,切勿使用.Python有这么多更好的选择(调度字典,getattr()等等),你不应该使用被称为安全漏洞eval().
最简单的方法就是创建一个字典.
class A(object):
pass
class B(object):
pass
namedclass = {'ID12345': A, 'ID2': A, 'B': B, 'AnotherB': B, 'ID01234': B}
Run Code Online (Sandbox Code Playgroud)
然后使用它(您的代码示例):
IDS = ["ID12345", "ID01234"]
ProcessDirector = ProcessDirector()
for id in IDS:
builder = namedclass[id]()
ProcessDirector.construct(builder)
builder.run()
Run Code Online (Sandbox Code Playgroud)