Python 使用跨多个模块共享的变量作为默认函数参数
这个包含3个脚本的最小示例最好地说明了当前的问题: foo.pyPython 使用跨多个模块共享的变量作为默认函数参数,python,Python,这个包含3个脚本的最小示例最好地说明了当前的问题: foo.py global_val = [0] from foo import global_val def work(val=global_val[0]) print("global_val: ", global_val[0]) print("val: ", val) from bar import work import foo if __name__ == '__main__': foo.global_va
global_val = [0]
from foo import global_val
def work(val=global_val[0])
print("global_val: ", global_val[0])
print("val: ", val)
from bar import work
import foo
if __name__ == '__main__':
foo.global_val[0] = 1
work()
bar.py
global_val = [0]
from foo import global_val
def work(val=global_val[0])
print("global_val: ", global_val[0])
print("val: ", val)
from bar import work
import foo
if __name__ == '__main__':
foo.global_val[0] = 1
work()
main.py
global_val = [0]
from foo import global_val
def work(val=global_val[0])
print("global_val: ", global_val[0])
print("val: ", val)
from bar import work
import foo
if __name__ == '__main__':
foo.global_val[0] = 1
work()
我期望的输出是什么:
global_val: 1
val: 1
global_val: 1
val: 0
实际输出:
global_val: 1
val: 1
global_val: 1
val: 0
我不明白为什么bar.py
中val
的默认参数不是1
。我很困惑,因为在调用work()
之前,我清楚地更新了global\u val
,但出于某种原因,旧值仍然用作默认函数参数
在bar.py
中导入global\u val
时,默认参数似乎是以某种方式预先计算的。Python代码不是应该在运行时进行动态编译吗
如果有帮助的话,我正在使用Python 3.6
item = 0
def bar(val=item):
print(val)
bar(2) # 2
bar() # 0
item = 1
bar() # 0
这与默认参数有关,而不是全局参数。默认参数只计算一次,而不是每次调用函数。如果我没有错,那么在您从bar.py导入work func时,将执行默认参数,并且无论您以后是否更改值,因为默认参数已在导入时“声明”,由于默认参数只计算一次,关键是
def work(val=global\u val[0]):
在导入时进行计算(例如,当在main.py中点击from bar import work
时)Python中函数的默认参数在函数运行时计算并存储在其签名中
因此,操作顺序为:
运行main.py
从条形图导入工作
找到并加载条
来自foo导入全局值
找到并加载foo
def工作(val=global\u val[0]):
构造一个名为work
的函数,并计算其默认参数(global\u val[0]==0
)
foo.global\u val[0]=1
调用工作
由于默认值在定义/导入时是固定的,因此最好设置一个标志或无作为默认值,并在函数头部测试该标志,然后在执行时从可用范围(当然)分配一个对象作为所需的实际默认值。我想当编译器看到这一点时:
def work(val=global_val[0])
val的默认值将是当时的全局值[0]。稍后将其设置为不同的值不会更改函数定义,即,如果没有为该参数提供参数,则将val变量设置为0(这是global_val的第一个元素)
请尝试以下方法:
def work(val=None):
if not val:
global global_val
val = global_val[0]
在这里,您将val设置为可以捕获的已知值,在本例中为None,然后设置正确的值。使用关键字global可确保使用全局命名空间中的变量。如果在编译函数定义之后更改了全局值,则这将设置正确的全局值