Os dois snippets fazem coisas diferentes, então não é uma questão de gosto, mas uma questão de qual é o comportamento correto em seu contexto. A documentação do Python explica a diferença, mas aqui estão alguns exemplos:
Anexo A
class Foo:
def __init__(self):
self.num = 1
Isso se liga num
às instâncias Foo . A alteração neste campo não é propagada para outras instâncias.
Portanto:
>>> foo1 = Foo()
>>> foo2 = Foo()
>>> foo1.num = 2
>>> foo2.num
1
Prova B
class Bar:
num = 1
Isso se liga num
à classe Bar . As mudanças são propagadas!
>>> bar1 = Bar()
>>> bar2 = Bar()
>>> bar1.num = 2
>>> bar2.num
1
>>> Bar.num = 3
>>> bar2.num
3
>>> bar1.num
2
>>> bar1.__class__.num
3
Resposta real
Se eu não exigir uma variável de classe, mas apenas precisar definir um valor padrão para minhas variáveis de instância, os dois métodos são igualmente bons? Ou um deles mais 'pitônico' do que o outro?
O código na exposição B está totalmente errado para isso: por que você deseja vincular um atributo de classe (valor padrão na criação da instância) à única instância?
O código na prova A está correto.
Se você quiser fornecer padrões para variáveis de instância em seu construtor, eu faria o seguinte:
class Foo:
def __init__(self, num = None):
self.num = num if num is not None else 1
... ou mesmo:
class Foo:
DEFAULT_NUM = 1
def __init__(self, num = None):
self.num = num if num is not None else DEFAULT_NUM
... ou mesmo: (preferível, mas se e somente se você estiver lidando com tipos imutáveis!)
class Foo:
def __init__(self, num = 1):
self.num = num
Desta forma, você pode fazer:
foo1 = Foo(4)
foo2 = Foo()
self.attr = attr or []
dentro do__init__
método. Alcança o mesmo resultado (eu acho) e ainda é claro e legível.