Python 不会从导入的函数更新全局变量

python won't update globals from imported function

提问人:jeffpkamp 提问时间:10/21/2023 更新时间:10/21/2023 访问量:54

问:

我编写了一个脚本来解析命令行中的参数。它有一个称为的函数,该函数解析来自用户的命令字符串,以创建一个使用变量名称和关联值调用的字典,并返回字典。如果我将函数包含在主脚本中,我只需在函数内部执行即可将这些变量移动到 globals() 列表中。getFlagssys.argvmyVarsglobals().update(myVars)

但是,当我保存此函数并导入它时,更新功能不起作用,我被迫使用 .这对我来说很好用,但让一些使用我的脚本的人感到困惑。globals().update(getFlags(...))

如何使用导入的函数使其更新全局变量?

def getFlags(commandString,usage="No usage was provided"):
   ....
   globals().update(myVars)
   return myVars


getFlags("...")

#My variables are now in the global scope
from myScripts import getFlags

getFlags("...") 
#Oh no, variables not in global scope
globals().update(getFlags("...")
#Now the variables are in the global scope
全球

评论

4赞 Silvio Mayolo 10/21/2023
如果我调用的函数将一个变量引入全局范围,我肯定会感到困惑,更不用说一堆变量了。只需返回一本字典,不要像您应该的那样混淆全局范围;每个使用此工具的人都会感谢您。
2赞 Brian61354270 10/21/2023
您可能对以下内容感兴趣:为什么全局状态如此邪恶?使用全局变量的利弊是什么?。对于全局变量来说,这看起来是一个非常糟糕的用例。将信息显式传递到函数和从函数传递信息,而不是依赖一些隐藏状态,这不是容易得多吗?
0赞 jeffpkamp 10/21/2023
@SilvioMayolo 但是,如果程序告诉你它会这样工作,你会感到困惑吗?大多数情况下,我这样做是为了符合我用真正只使用一个作用域的语言编写的类似程序,但我知道作用域在 Python 中会导致混淆。
2赞 Silvio Mayolo 10/21/2023
@jeffpkamp我猜你说的是,也许是MATLAB?我听说过这个论点被用来证明很多 Python 暴行的合理性。“这就是我在 X 中的做法”并不是在 Python 中做同样事情的理由。

答:

2赞 Blckknght 10/21/2023 #1

尽管有这个名字,但全局命名空间不仅仅是一回事。每个模块都有单独的全局命名空间。运行代码时,它使用编写代码的模块的全局命名空间。

这就是为什么您拨打的电话无法按预期工作的原因。它更新模块的全局命名空间,而不是调用代码的全局命名空间。globals.updategetFlagsmyScripts

您可能可以用来遍历堆栈帧并找到调用方的全局命名空间,但我强烈怀疑这不值得。向模块的全局命名空间添加内容,尤其是使用用户提供的数据似乎是一个非常糟糕的主意。如果它重新定义了你的一个功能呢?或者内置的,比如 or ?inspectlistprint

评论

0赞 jeffpkamp 10/21/2023
谢谢。我以为是这样的,但找不到任何关于它的文档。现在你解释了它,我正在寻找关于它的文档。这是一个非常标准的参数解析器,与 Python(或任何语言)中的任何其他工具一样,您可以以不正确的方式使用它,从而产生意外和不良的结果。有点像全球范围:)
0赞 jeffpkamp 10/21/2023
对此进行深入研究,我很好奇模块变量在全局范围内是如何显示的,即使它们在范围内。我错过了模块的对象行为,因为我使用的是该方法,因此该模块在全局范围内不可见。__builtins____builtins__from module import method