Простой питон oo выпуск - PullRequest
       18

Простой питон oo выпуск

4 голосов
/ 19 апреля 2010

Посмотрите на этот простой пример. Я не совсем понимаю, почему o1 печатает «Hello Alex» дважды. Я думаю, что по умолчанию self.a всегда сбрасывается в пустой список. Может ли кто-нибудь объяснить мне, что здесь обоснование? Большое вам спасибо.

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

Ответы [ 2 ]

12 голосов
/ 19 апреля 2010

Прочтите эту ловушку об изменяемых аргументах функции по умолчанию: 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__), а не во время определения.

6 голосов
/ 19 апреля 2010

Аргументы по умолчанию в Python, например:

def blah(a="default value")

оцениваются один раз и повторно используются в каждом вызове, поэтому при изменении a вы изменяете глобально. Возможное решение:

def blah(a=None):
  if a is None
    a = []

Подробнее об этой проблеме можно прочитать на: http://www.ferg.org/projects/python_gotchas.html#contents_item_6

По сути, никогда не используйте изменяемые объекты, такие как списки или словари, для значения по умолчанию для аргумента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...