У меня есть класс TextBuffer
. Он имеет функцию __init__
, которая может использоваться для передачи начального значения для содержимого TextBuffer
. Если значение не передано, оно должно использовать пустой список как значение по умолчанию.Метод __init__ получает значение, пока ни один не передан
Класс имеет метод добавить, чтобы добавить текст в TextBuffer:
a = TextBuffer()
a += "TEXT"
По какой-то причине вызова метода __init__
без параметров не использует значение по умолчанию []
для lst
, но ранее добавленную стоимость другого экземпляра TextBuffer
, которое не находится в __init__
вызова
a = TextBuffer()
a += "BUFFER A"
b = TextBuffer() ### lst in the __init__ call has the value of ["BUFFER A"]
b += "BUFFER B"
Я понятия не имею, почему это происходит. Может быть, я делаю что-то не так в методе __add__
?
Пожалуйста, обратите внимание полный пример кода:
import pprint
### Two functions for byte/string conversion in Python3
def b(x):
if (type(x) == type(b'')):
return x
else:
return x.encode(encoding='UTF-8')
def s(x):
if (type(x) == type(b'')):
return x.decode(encoding='UTF-8')
else:
return x
class TextBuffer():
def __init__(self, lst = [], maxlines = None):
self.content = []
if (type(lst) == type([])):
if (len(lst) > 0):
print("INIT got a nonempty lst value:")
pprint.pprint(lst)
print("------------------------------")
self.content = lst
def __getitem__(self, i):
try:
return self.content[i]
except IndexError:
return None
def __iter__(self):
for line in self.content:
yield line
def __contains__(self, item):
return item in self.content
def __len__(self):
return len(self.content)
def __add__(self, item):
self.content.append(item)
return self
def __radd__(self, item):
return self.__add__(item)
def __repr__(self):
result = ""
for line in self.content:
if (type(line) == type(b"")):
result+=s(line)
else:
result+=line
return result
def __str__(self):
return repr(self)
def __unicode__(self):
return repr(self.content)
### TextBuffer INIT with empty list creates an empty textbuffer
a = TextBuffer(lst=[])
print("a = TextBuffer(lst=[])")
a += "BUFFER A"
### TextBuffer INIT with empty list creates an empty textbuffer
b = TextBuffer(lst=[])
print("b = TextBuffer(lst=[])")
b += "BUFFER B"
print("Content of TextBuffer a:")
print(a)
print("Content of TextBuffer b:")
print(b)
print("-------------------------")
### TextBuffer INIT without any parameters should use default value for lst of []
### So an empty list. Should be the same as TextBuffer(lst=[])
a = TextBuffer()
print("a = TextBuffer()")
a += "BUFFER A"
### TextBuffer INIT without any parameters should use default value for lst of []
### So an empty list. Should be the same as TextBuffer(lst=[])
### But now, the value of lst is not [], it is the string added to TextBuffer 'a': ['BUFFER A']
b = TextBuffer()
print("b = TextBuffer()")
b += "BUFFER B"
print("Content of TextBuffer a:")
print(a)
print("Content of TextBuffer b:")
print(b)
Поскольку у вас есть изменяемая вещь как аргумент по умолчанию ('[]'). Все экземпляры разделяют _that_ list, поэтому, если один из них добавляет к нему элемент, все они добавляются. Это дубликат многих вопросов. – RemcoGerlich
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#default-parameter-values – RemcoGerlich
Там _are_ ситуации, где вы можете безопасно использовать изменяемый по умолчанию аргумент, это не один из них. –