Простая проблема с python oo
Посмотрите этот простой пример. Я не совсем понимаю, почему o1 печатает "Hello Alex" дважды. Я бы подумал, что из-за по умолчанию self.a всегда reset в пустой список. Может ли кто-нибудь объяснить мне, что здесь есть? Большое вам спасибо.
class A(object):
def __init__(self, a=[]):
self.a = a
o = A()
o.a.append('Hello')
o.a.append('Alex')
print ' '.join(o.a)
# >> prints Hello Alex
o1 = A()
o1.a.append('Hello')
o1.a.append('Alex')
print ' '.join(o1.a)
# >> prints Hello Alex Hello Alex
Ответы
Ответ 1
Аргументы по умолчанию в Python, например:
def blah(a="default value")
оцениваются один раз и повторно используются в каждом вызове, поэтому при изменении вы изменяете глобально. Возможное решение:
def blah(a=None):
if a is None
a = []
Вы можете узнать больше об этой проблеме: http://www.ferg.org/projects/python_gotchas.html#contents_item_6
В принципе, никогда не используйте изменяемые объекты, например списки или словари по значению по умолчанию для аргумента.
Ответ 2
Прочитайте этот Pitfall о изменяемых аргументах функции по умолчанию:
http://www.ferg.org/projects/python_gotchas.html
Короче говоря, когда вы определяете
def __init__(self,a=[])
Список, на который ссылается self.a по умолчанию, определяется только один раз, во время определения, а не во время выполнения. Поэтому каждый раз, когда вы вызываете o.a.append
или o1.a.append
, вы изменяете один и тот же список.
Типичный способ исправить это - сказать:
class A(object):
def __init__(self, a=None):
self.a = [] if a is None else a
Переместив self.a=[]
в тело функции __init__
, во время выполнения создается новый пустой список (каждый раз при вызове __init__
), а не во время определения.