Python 如何冻结可变的默认参数值?

Python 如何冻结可变的默认参数值?,python,python-3.x,function,metaprogramming,mutability,Python,Python 3.x,Function,Metaprogramming,Mutability,Python选择遵循只计算函数签名一次的设计决策。所以这个代码: def测试(x=[]): x、 附加(5) 返回x 打印(test()) 打印(test()) 印刷品: [5] [5,5] 我知道可以使用None作为默认值,如果None,则可以更改函数中的参数值。 如何编写一些代码来更改测试的行为,以便每次调用函数时都重新计算默认参数?解决方案可以包括装饰器,并使用类作为默认值。我们可以使用函数的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>

Python选择遵循只计算函数签名一次的设计决策。所以这个代码:

def测试(x=[]): x、 附加(5) 返回x 打印(test()) 打印(test()) 印刷品:

[5]

[5,5]

我知道可以使用
None
作为默认值,如果
None,则可以更改函数中的参数值。



如何编写一些代码来更改
测试的行为
,以便每次调用函数时都重新计算默认参数?解决方案可以包括装饰器,并使用类作为默认值。

我们可以使用函数的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>属性来“冻结”默认值(和
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

现在:

印刷品:

[5]

[5]

甚至:

@freeze_defaults
def test(x=['hello!']):
    x.append(5)
    return x

print(test())
print(test())
印刷品:

[你好,5]

[你好,5]


这就引入了线程安全漏洞。如果另一个线程在
func.\uuuuu defaults\uuuu
赋值和调用
func
之间中断
包装程序
,则两个线程可能最终使用相同的
\uuuu defaults\uuuu
,使用
time.sleep
调用让线程在正确的位置彼此中断。它在仅关键字参数上也会失败,这些参数使用
\uuuuuukwdefaults\uuuudefaults>而不是
\uuudefaults\uudefaults
。感谢您的详细反馈。已更新该函数以支持默认值。
@freeze_defaults
def test(x=[]):
    x.append(5)
    return x

print(test())
print(test())
@freeze_defaults
def test(x=['hello!']):
    x.append(5)
    return x

print(test())
print(test())