我的应用程序通过exec执行存储在配置文件中的python逻辑位,如:
"foo() + 2"
此逻辑通常引用我存储在名为“standard”的模块中的符号。例如,在上面,您可以看到逻辑访问方法foo(),并且foo在standard.py中定义:
def foo():...
为了让逻辑能够访问标准中的符号,我将这些方法从标准中提取到字典中,如下所示:
import standard
my_globals = standard.__dict__
然后我将一些其他相关的符号添加到my_globals(我在这里没有显示)并将它们提供给逻辑,当我执行它时:
exec("foo() + 2", my_globals)
这很有效。当我从foo()内部查看globals()时,我可以看到我在模块standard.py中定义的其他方法以及我上面提到的其他相关符号,foo()可以访问所有这些东西。
当我想要为逻辑提供另一个函数模块时,问题就出现了。假设我有一个名为custom.py的模块,其中包含我希望逻辑访问的其他符号。我试图通过这样做来使这些符号可用:
import custom
my_globals.update(custom.__dict__)
我们现在说我的逻辑是“bar()+ 1”,其中“bar”是在custom.py中定义的。 bar()也想访问我添加到my_globals中的一些相关的其他符号。
我遇到的问题是,custom中的代码只能看到custom.py中定义的符号,而不是my_globals中存储的所有其他符号。 IE,bar()看不到foo(),也看不到我藏在my_globals中的其他东西。
然而foo()可以。它的代码可以看到我在标准中定义的任何其他方法,以及自定义中定义的符号,以及我插入my_globals的“额外”符号。
为什么会这样?我的期望是正在执行的逻辑是在my_globals的内容的上下文中运行的,所以看起来foo()和bar()都应该能够访问my_globals中的任何和所有符号。
我怀疑这与我如何创建my_globals有关。任何见解将不胜感激!
答案 0 :(得分:1)
以下是一些见解:
“为了让逻辑能够访问标准中的符号,我将这些方法从标准中提取到字典中,如下所示:”
import standard
my_globals = standard.__dict__
不完全。您只需创建一个现在指向my_globals
的局部变量standard.__dict__
。每当您更新my_globals
时,您确实只是更新standard.__dict__
。
当您将其他符号添加到my_globals
时,您只需将它们添加到standard.__dict__
。
通话:
exec("foo() + 2", my_globals)
在standard.py中定义foo
时效果很好,因为您已将所有其他方法添加到此模块中 - 您现在可以访问所有这些方法。
当你这样做时:
import custom
my_globals.update(custom.__dict__)
您已将custom.py中的“符号”添加到标准模块中。在此之后,标准中的所有函数都可以从custom.py访问函数
不幸的是,custom.py本身无法直接访问standard.py中的方法(除非您导入它们)。在custom.py中,您可以看到您创建的所有内容现在都是标准的:
(来自custom.py):
import sys
def custom_foo():
print(dir(sys.modules['standard'])) # shows that you've put everything in here
sys.modules['standard'].foo() # calls foo from standard.py (assuming you've imported standard in your main pgm)
上面真的很难看 - 你可以添加一个:
from standard import *
位于custom.py的顶部,您可以访问已添加到__dict__
的所有内容。
我怀疑你真的希望用整个exec
做你正在尝试的事情,但我不确定你的用例是什么。
修改强>
如果您确实希望所有附加到my_globals
的符号可用于custom.py的方法,则可以调用:
custom.__dict__.update(my_globals)
在此之后,custom.py中的函数可以访问您添加到标准中的所有内容。 dict (又名my_globals)。 (您还使用my_globals
中的同名函数覆盖了custom.py中定义的任何函数
请注意,以这种方式做事非常不典型(读:有些不明智)。