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

2024-10-02 10:32:47 发布

您现在位置:Python中文网/ 问答频道 /正文

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

下面是我所拥有内容的一个高度简化的版本。有一个带有函数的文件hat.py,该函数需要一个符号作为输入,并返回一个添加了后缀“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将不会在此处定义,并将返回一个错误。每次使用hat之后,我都需要使用import将新变量添加到名称空间中。这不是一个选项,因为我有数百个符号和hat的数百种用法。我也不想只是先发制人地导入数千个符号

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


Tags: 文件项目方法函数frompyimport名称
2条回答

这回答了问题,但我认为这不是编写代码的好方法:

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)

回答我自己的问题,灵感来自库巴图卡的建议。可以将模块变量指向全局命名空间。通过用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)

相关问题 更多 >

    热门问题