动态实例化对象
Dynamically instantiating objects
我正在尝试从字符串中实例化一个对象。具体来说,我正在尝试改变这一点:
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)
这个看似奇怪的任务的动机是能够在数据库中存储不同版本的映射脚本,然后 retrieve/use 根据需要使用它们(强调 map()
方法的多态性).
以上方法无效。出于某种原因,eval()
抛出 SyntaxError: invalid syntax.
我不明白这一点,因为它与第一种情况下导入的文件相同。 eval()
不能用来定义 类 有什么原因吗?
我应该指出,我知道 eval()
周围的安全问题。如果有的话,我很想听听其他方法。我唯一能想到的另一件事是获取脚本,将其物理保存到节点包目录中,然后导入它,但这似乎更疯狂。
你需要使用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。
我正在尝试从字符串中实例化一个对象。具体来说,我正在尝试改变这一点:
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)
这个看似奇怪的任务的动机是能够在数据库中存储不同版本的映射脚本,然后 retrieve/use 根据需要使用它们(强调 map()
方法的多态性).
以上方法无效。出于某种原因,eval()
抛出 SyntaxError: invalid syntax.
我不明白这一点,因为它与第一种情况下导入的文件相同。 eval()
不能用来定义 类 有什么原因吗?
我应该指出,我知道 eval()
周围的安全问题。如果有的话,我很想听听其他方法。我唯一能想到的另一件事是获取脚本,将其物理保存到节点包目录中,然后导入它,但这似乎更疯狂。
你需要使用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。