除非有安全漏洞eval
,否则不能在其中使用名称a
,mapper.py
除非该名称在某处定义mapper.py
或从另一个模块导入。没有办法让mapper.py
自动和静默地访问a
来自不同模块的值。
此外,如果您只是在示例中的字典中使用它,则将在创建字典后a.foo
立即进行评估。它不会等到您真正调用该函数;一旦它评估a.foo
创建字典,它就会失败,因为它不知道是什么a
。
您可以通过将元素包装在函数中来解决第二个问题(为简洁起见,使用 lambda):
Mapper = {'test': lambda: a.foo}
. . . 但这仍然无济于事,除非你能以某种方式a
在里面有空mapper.py
。
一种可能性是Mapper
通过“神秘”对象参数化您的对象,然后将该对象从外部传入:
# mapper.py
Mapper = {'test': lambda a: a.foo}
# other module
from mapper import Mapper
Mapper['test'](a)()
或者,类似于建议的内容,您可以以某种方式mgilson
“注册”该对象。这使您只需传递对象一次即可注册它,然后您不必每次调用都传递它:a
Mapper
a
# mapper.py
Mapper = {'test': lambda a: Mapper['a'].foo}
# other module
from mapper import Mapper
Mapper['a'] = a
Mapper['test']()()
请注意末尾的两组括号:一组用于评估 lambda 并提取您要调用的函数,第二组用于实际调用该函数。Mapper['a']
您可以通过使用模块级变量而不是用作参考来进行类似的处理:
# mapper.py
Mapper = {'test': lambda: a.foo}
# other module
import mapper
Mapper = mapper.Mapper
mapper.a = a
Mapper['test']()()
请注意,这需要您import mapper
在其他模块中设置模块变量。
您可以通过使用自定义类Mapper
而不是常规 dict 来简化这一点,并让该类在其中做一些工作__getitem__
以查看“已知位置”(例如,读取一些模块变量)以用作评估的基础a
。不过,这将是一个更重的解决方案。
最重要的是,您根本不能(再次,不使用eval
或其他此类漏洞)编写mapper.py
使用未定义变量的代码a
,然后a
在另一个模块中定义一个变量并mapper.py
自动知道这一点。某处必须有一些代码行“告诉”您希望它使用mapper.py
什么值。a