重新分配python模块的变量,但函数使用该变量作为默认值不会更改

重新分配python模块的变量,但函数使用该变量作为默认值不会更改,python,Python,下面是示例代码: # b.py c = False def d(i=c): print(i, c) 我想写a.py,让b.d的输出为真,真: 但结果是假的,真的 那么,为什么以及如何获得它呢 在回答后写 原因: # `inspect` may be useful import inspect v = True def f(i=v): print(i, v) s = inspect.signature(f) s.parameters Out[6]: mappingproxy({

下面是示例代码:

# b.py
c = False
def d(i=c):
    print(i, c)
我想写a.py,让b.d的输出为真,真:

但结果是假的,真的

那么,为什么以及如何获得它呢

在回答后写

原因:

# `inspect` may be useful
import inspect
v = True
def f(i=v):
    print(i, v)

s = inspect.signature(f)
s.parameters
Out[6]: mappingproxy({'i': <Parameter "i=True">})

这是不必要的复杂-我们可以将您的问题归结为几行:

default = "Before"

def foo(bar=default):
    print(bar)

foo()              # "Before"
default = "After"
foo()              # "Before"
您似乎期望的行为是,在default=after之后,调用foo将在之后打印。但它以前一直在印刷

Python将对函数的默认参数求值一次并将其锁定。正如我们在上面的代码片段中看到的那样,稍后将default的名称重新指定给其他名称没有任何效果

相反,当人们希望列表作为默认参数时,可以使用通常建议的方法:

default = "Before"

def foo(bar=None):
    if bar is None:
        bar = default
    print(bar)

foo()              # "Before"
default = "After"
foo()              # "After"

在本例中,您并没有试图更改默认参数,而是在未指定参数时更改分配给bar的内容。每次在没有参数的情况下调用foo时,都会将其赋值为None,然后函数内部的逻辑将查找并使用全局默认值。

这是不必要的复杂-我们可以将您的问题归结为几行:

default = "Before"

def foo(bar=default):
    print(bar)

foo()              # "Before"
default = "After"
foo()              # "Before"
您似乎期望的行为是,在default=after之后,调用foo将在之后打印。但它以前一直在印刷

Python将对函数的默认参数求值一次并将其锁定。正如我们在上面的代码片段中看到的那样,稍后将default的名称重新指定给其他名称没有任何效果

相反,当人们希望列表作为默认参数时,可以使用通常建议的方法:

default = "Before"

def foo(bar=None):
    if bar is None:
        bar = default
    print(bar)

foo()              # "Before"
default = "After"
foo()              # "After"

在本例中,您并没有试图更改默认参数,而是在未指定参数时更改分配给bar的内容。每次在没有参数的情况下调用foo时,它将被赋值为None,然后函数内部的逻辑将查找并使用全局默认值。

这是因为默认值在创建函数时计算一次

def d(i=c):
    print(i, c)
这里,在导入b行之后,d函数变为

def d(i=False):
    print(i, c)

因此,更改c对d中i的默认值没有影响。

这是因为默认值在创建函数时计算一次

def d(i=c):
    print(i, c)
这里,在导入b行之后,d函数变为

def d(i=False):
    print(i, c)

因此,更改c对d中i的默认值没有影响。

您不能随心所欲。最好的方法是编写ugh def di=None:然后在函数内部,如果i为None:i=c。这与使用空列表作为默认参数可能导致意外结果的原因相同。我的错误!立即更改您正在更改模块b中c的值,但模块b中的d函数已被解析和计算,其参数i的默认值已设置为False。如果Python总是要重新计算它的函数签名,那么它的速度会慢得多。我明白了,所以没有简单的方法可以在中更改STRICT=True并让handle\u error引发错误。你不能做你想做的事情。最好的方法是编写ugh def di=None:然后在函数内部,如果i为None:i=c。这与使用空列表作为默认参数可能导致意外结果的原因相同。我的错误!立即更改您正在更改模块b中c的值,但模块b中的d函数已被解析和计算,其参数i的默认值已设置为False。如果Python总是要重新计算它的函数签名,那么它的速度会慢得多。我明白了,所以在中更改STRICT=True并让handle\u error引发错误是不容易的。