Python:在类方法上使用contextmanager的意外行为
作者:互联网
参见英文答案 > “Least Astonishment” and the Mutable Default Argument 32个
> Python constructor and default value 4个
我正在尝试使用Python中的with..as contruct来简化“可逆计算”代码的编写.但是,在类方法上使用@contextmanager似乎会更改未来类实例的默认初始化. Python 2.6和3.1具有相同的行为.以下是展示此行为的简单示例:
#!/usr/bin/env python
import contextlib
class SymList:
def __init__(self, L=[]):
self.L = L
@contextlib.contextmanager
def SymAdd(self, a):
self.L.append(a)
yield
self.L.append(a)
SL = SymList()
with SL.SymAdd(3):
SL.L.append(5)
print(SL.L) # Expect and see [3, 5, 3]
SL2 = SymList()
print(SL2.L) # Expect [] and see [3, 5, 3]
>为什么SL2不是SymList的新实例?
> SL2.L数据成员如何引用SL.L数据成员?
解决方法:
此行为是由于mutable default arguments如何在Python中工作.
尝试将SymList .__ init __()更改为以下内容:
def __init__(self, L=None):
if L is None:
self.L = []
else:
self.L = L
当您在一个实例中修改self.L时,您还修改了传递给SymList .__ init __()的L,因此您的代码的结果是所有实例在首次初始化实例时将共享相同的L属性.
标签:python,with-statement,contextmanager 来源: https://codeday.me/bug/20190714/1455478.html