除非有安全漏洞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“注册”该对象。这使您只需传递对象一次即可注册它,然后您不必每次调用都传递它:aMappera
# 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