如何在不使用 exec(open(...)) 的情况下加载可以添加全局变量的函数?

How can I load a function, which can add global variables, without using exec(open(...))?

我有一个运行良好的 SymPy python 项目,但我目前需要在每个文件的开头使用 exec(open(...))。我想知道我是否可以避免这种情况?部分原因是我读到 exec 应该避免购买 我还想发现我当前方法的任何可能替代方案。

以下是我所拥有内容的高度简化版本。有一个带有函数的文件 hat.py,它需要一个符号作为输入,并且 return 是一个添加了后缀 'h' 的新符号。重要的是,它还将这个新符号添加到全局命名空间中。

from sympy import Symbol

def hat(var):
    nameh = str(var)+"h"
    globals()[nameh] = Symbol(nameh)
    return globals()[nameh]

我的项目涉及多个文件,需要使用hat()功能如下。

from sympy import Symbol

exec(open("hat.py").read()) 

x = Symbol('x')
e1 = x + hat(x)
print(xh + e1)

如果 hat() 来自 import 语句,则 xh 不会在此处定义并且 return 会出错。我需要在每次使用 hat 后使用 import 将新变量添加到命名空间。这不是一个选项,因为我有数百个符号和数百个 hat 的使用。我也不想抢先导入数千个符号。

有没有其他方法可以加载能够动态添加变量到顶级命名空间的函数?

这回答了问题,但我认为这不是一个好的编码方式:

from sympy import Symbol

def hat(var,namespace):
    nameh = str(var)+"h"
    namespace[nameh] = Symbol(nameh)
    return namespace[nameh]

然后在项目中:

from sympy import Symbol
from hat import hat


x = Symbol('x')
e1 = x + hat(x,globals())
print(xh + e1)

根据 kubatucka 的建议回答我自己的问题。可以将模块变量指向全局命名空间。通过用 import 行替换 exec() 行并设置 globals() 命名空间行,这给了我所有的功能。

函数文件hat.py:

from sympy import Symbol

def set_global_namespacece(namespace):
    global global_namespace
    global_namespace = namespace
    
def hat(var):
    nameh = str(var)+"h"
    global_namespace[nameh] = Symbol(nameh)
    return global_namespace[nameh]

项目文件x_eqns.py:

from sympy import Symbol

from hat import *
set_global_namespacece(globals())

x = Symbol('x')
e1 = x + hat(x)
print(xh + e1)