【问题标题】:Dynamically instantiating objects动态实例化对象
【发布时间】:2016-02-05 22:31:35
【问题描述】:

我正在尝试从字符串实例化一个对象。具体来说,我正在尝试改变这一点:

from node.mapper import Mapper
mapper = Mapper(file)
mapper.map(src, dst)

变成这样:

with open('C:.../node/mapper.py', 'r') as f:
    mapping_script = f.read()

eval(mapping_script)
mapper = Mapper(file)
mapper.map(src, dst)

这个看似奇怪的任务的动机是能够在数据库中存储不同版本的映射脚本,然后根据需要检索/使用它们(强调map() 方法的多态性)。

以上行不通。出于某种原因,eval() 抛出 SyntaxError: invalid syntax. 我不明白这一点,因为它与在第一种情况下导入的文件相同。 eval() 不能用于定义类有什么原因吗?

我应该注意,我知道围绕 eval() 的安全问题。如果有的话,我很想听听其他方法。我能想到的唯一另一件事是获取脚本,将其物理保存到节点包目录中,然后导入它,但这似乎更疯狂。

【问题讨论】:

    标签: python object objectinstantiation


    【解决方案1】:

    你需要使用exec:

    exec(mapping_script)
    

    eval() 仅适用于表达式。 exec() 适用于陈述。典型的 Python 脚本包含语句。

    例如:

    code = """class Mapper: pass"""
    exec(code)
    mapper = Mapper()
    print(mapper)
    

    输出:

    <__main__.Mapper object at 0x10ae326a0>
    

    确保您在模块级别调用 exec()(Python 3,在 Python 2 中它是一个语句)。当您在函数中调用它时,您需要添加globals(),例如exec(code, globals()),以使对象在全局范围内可用,并在here 讨论的函数的其余部分中可用。

    【讨论】:

    • 它不起作用。即使在 mapping_script 中定义了 Mapper 类,以下实例化调用也会失败并抱怨 Mapper 未定义。
    • 是的。我通过调试器确认了它。我还将一个简单的变量定义放入文件中,并且定义得很好。这个问题似乎与 Mapper 从基类继承的事实有关,尽管在 mapper.py 中有一个 import 语句,但该类没有被导入。我还尝试将基类导入添加到运行 exec() 的脚本中,但这也不起作用。仍在尝试挖掘它...
    • @Gadzooks34:你使用的是哪个 Python 版本?这是在函数内部吗?
    • @user2357112:我使用的是 3.4。它实际上发生在静态类方法中。这很奇怪。调试器 (PyCharm) 显示 Mapper 成功定义为 exec() 之后的类型,但实例化调用仍然失败,并显示“'Mapper' is not defined”。
    • exec 在函数内吗?如果是这样,请按照this link 尝试exec(code, globals())
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-20
    • 1970-01-01
    相关资源
    最近更新 更多