如何更改可选函数参数的默认值



我需要将全局变量从b.py更改为a.py处的全局变量S,但它在a.py的函数中用作默认值。

a.py

S = "string"

def f(s=S):
print(s)
print(S)

b.py

import a

def main():
a.S = "another string"
a.f()

if __name__ == "__main__":
main()

python b.py输出

string
another string

而不是预期的

another string
another string

如果我像这样用b.pya.f打电话

a.f(a.S)

这按预期工作,但是有没有办法更改默认变量值?

简短的回答是:你不能。

这样做的原因是函数默认参数是在函数定义时创建的,并且默认值并不意味着要重新定义。变量名称绑定到一个值一次,仅此而已,您无法将该名称重新绑定到另一个值。首先,让我们看一下全局范围内的变量:

# create a string in global scope
a = "string"
# b is "string"
b = a
a += " new" # b is still "string", a is a new object since strings are immutable

你现在刚刚将一个新名称绑定到"string",而"string new"是一个绑定到a的全新值,它不会改变b,str += str因为它返回一个新的str,使ab引用不同的对象。

函数也会发生同样的情况:

x = "123"
# this expression is compiled here at definition time
def a(f=x):
print(f)
x = "222"
a()
# 123

变量f在定义时使用默认值"123"进行定义。这无法更改。即使使用可变的默认值,例如在这个问题中:

x = []
def a(f=x):
print(x)
a()
[]
# mutate the reference to the default defined in the function
x.append(1)
a()
[1]
x
[1]

默认参数已定义,并且名称f绑定到无法更改的值[]。您可以改变与f关联的值,但不能将f绑定到新值作为默认值。为了进一步说明:

x = []
def a(f=x):
f.append(1)
print(f)
a()
x
[1]
# re-defining x simply binds a new value to the name x
x = [1,2,3]
# the default is still the same value that it was when you defined the
# function, albeit, a mutable one
a()
[1, 1]

最好是 A) 将全局变量作为参数传递给函数,或者 B) 将全局变量用作global。如果要更改要使用的全局变量,请不要将其设置为默认参数,而是选择更合适的默认值:

# some global value
x = "some default"
# I'm choosing a default of None here
# so I can either explicitly pass something or
# check against the None singleton
def a(f=None):
f = f if f is not None else x
print(f)
a()
some default
x = "other default"
a()
other default
a('non default')
non default

相关内容

  • 没有找到相关文章

最新更新