可以使用字符串来实例化一个类吗?
我在 Python 中使用 Builder 模式来分隔一堆不同的配置可能性。 基本上,我有一堆名为 ID...
的类(例如 ID12345
)。 这些都继承自 Builder 基类。 在我的脚本中,每次运行此应用程序时,我都需要为每个类(大约 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 添加到 IDS 列表中,而不是在整个代码中添加新的 ID。
编辑:
看起来根据数据的来源有不同的意见。 这些 ID 被输入到其他人无法访问的文件中。 我没有从命令行读取字符串,并且我希望在将来添加新 ID 时能够进行尽可能少的更改。
I'm using a Builder pattern in Python to separate a bunch of different configuration possibilities. Basically, I have a bunch of classes that are named ID...
(e.g. ID12345
). These all inherit from the base Builder class. In my script, I need to instantiate an instance for each class (about 50) every time this app runs. So, I'm trying to see if instead of doing something like this:
ProcessDirector = ProcessDirector()
ID12345 = ID12345()
ID01234 = ID01234()
ProcessDirector.construct(ID12345)
ProcessDirector.construct(ID01234)
ID12345.run()
ID01234.run()
Can I do something like this (I know this doesn't work):
IDS = ["ID12345", "ID01234"]
ProcessDirector = ProcessDirector()
for id in IDS:
builder = id() #some how instantiate class from string
ProcessDirector.construct(builder)
builder.run()
That way, when I need to add a new one in the future, all I have to do is add the id to the IDS list, rather than peppering the new ID throughout the code.
EDIT:
Looks like there are different opinions based on where the data is coming from. These IDs are entered in a file that no one else has access to. I'm not reading the strings from the command line, and I'd like to be able to do as little alteration when adding a new ID in the future.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果您想避免使用 eval(),您可以这样做:
前提是该类是在当前作用域中定义(或导入)的。
If you wanted to avoid an eval(), you could just do:
Provided that the class is defined in (or imported into) your current scope.
不确定这是否是您想要的,但这似乎是一种更 Pythonic 的方式来实例化字符串中列出的一堆类:
Not sure this is what you want but it seems like a more Pythonic way to instantiate a bunch of classes listed in a string:
如果可以的话,永远不要使用
eval()
。 Python 有如此许多更好的选项(调度字典、getattr()
等),您永远不必使用名为eval()< 的安全漏洞/代码>。
Never use
eval()
if you can help it. Python has so many better options (dispatch dictionary,getattr()
, etc.) that you should never have to use the security hole known aseval()
.最简单的方法是创建一个字典。
然后使用它(您的代码示例):
Simplest way is to just create a dict.
Then use it (your code example):
我决定将接受的答案和对接受的答案发表评论。 我还添加了重载的
__getitem__
所以这看起来更像工厂模式。编辑:我添加了一些错误处理。
已编辑:置于宽松的知识共享许可下。 享受。
I decided to put together the accepted answer and a comment on the accepted answer. I also added the overloaded
__getitem__
so this looks more like a factory pattern.Edited: I added in some error handling.
Edited: Placed under permissive Creative Commons license. Enjoy.
你的问题遗漏了一些东西,所以我不得不猜测遗漏的东西。 请随意编辑您的问题以纠正遗漏。
这效果非常好。 它不是从字符串实例化——实际上你并不经常需要这样。 有时,但很少。 更常见的是,您需要从中获取实例对象的类对象列表。
如果您实际上是从命令行获取类名称,那么您需要进行以下小更改。
其他一切都保持不变。
[此外,如果可能,请尝试以小写字母开头实例变量名称。 以大写字母开头的名称通常是类名称。]
编辑
删除了
eval
。 尽管eval()
绝对不是安全漏洞。 仅当有人专门向恶意用户授予访问权限时,Eval(以及exec
和execfile
)才会出现问题。There's some stuff missing from your question, so I'm forced to guess at the omitted stuff. Feel free to edit your question to correct the omissions.
This works very nicely. It doesn't instantiate from a string -- in practice you don't often want this. Sometimes, but rarely. More commonly, you a list of class objects from which you want instance objects.
If you actually are getting your class names from the command line, then you'd make the following small change.
Everything else remains the same.
[Also, if possible, try to start instance variable names with lowercase letters. Names which start with Uppercase Letters are usually class names.]
Edit
Removed
eval
. In spite of the fact thateval()
is absolutely not a security hole. Eval (andexec
andexecfile
) are only a problem if someone specifically grants access to malicious users.