Эти два фрагмента делают разные вещи, поэтому дело не в вкусе, а в правильном поведении в вашем контексте. Документация Python объясняет разницу, но вот несколько примеров:
Выставка
class Foo:
def __init__(self):
self.num = 1
Это привязывается num
к экземплярам Foo . Изменение в этом поле не распространяется на другие экземпляры.
Таким образом:
>>> foo1 = Foo()
>>> foo2 = Foo()
>>> foo1.num = 2
>>> foo2.num
1
Приложение B
class Bar:
num = 1
Это привязывается num
к классу Bar . Изменения распространяются!
>>> bar1 = Bar()
>>> bar2 = Bar()
>>> bar1.num = 2
>>> bar2.num
1
>>> Bar.num = 3
>>> bar2.num
3
>>> bar1.num
2
>>> bar1.__class__.num
3
Актуальный ответ
Если мне не нужна переменная класса, а нужно только установить значение по умолчанию для моих переменных экземпляра, одинаково ли хороши оба метода? Или один из них более питонический, чем другой?
Код на выставке B явно неверен для этого: зачем вам связывать атрибут класса (значение по умолчанию при создании экземпляра) с единственным экземпляром?
Код на выставке А в порядке.
Если вы хотите указать значения по умолчанию для переменных экземпляра в своем конструкторе, я бы сделал следующее:
class Foo:
def __init__(self, num = None):
self.num = num if num is not None else 1
...или даже:
class Foo:
DEFAULT_NUM = 1
def __init__(self, num = None):
self.num = num if num is not None else DEFAULT_NUM
... или даже: (желательно, но тогда и только тогда, когда вы имеете дело с неизменяемыми типами!)
class Foo:
def __init__(self, num = 1):
self.num = num
Таким образом вы можете:
foo1 = Foo(4)
foo2 = Foo()
self.attr = attr or []
в рамках__init__
метода. Он дает тот же результат (я думаю), но при этом остается четким и читаемым.