Te dwa fragmenty robią różne rzeczy, więc nie jest to kwestia gustu, ale kwestia właściwego zachowania w Twoim kontekście. Dokumentacja Pythona wyjaśnia różnicę, ale oto kilka przykładów:
Eksponat A
class Foo:
def __init__(self):
self.num = 1
To wiąże num
się z instancjami Foo . Zmiana wprowadzona w tym polu nie jest propagowana do innych instancji.
A zatem:
>>> foo1 = Foo()
>>> foo2 = Foo()
>>> foo1.num = 2
>>> foo2.num
1
Dowód rzeczowy B
class Bar:
num = 1
To wiąże num
się z klasą Bar . Propagowane są zmiany!
>>> bar1 = Bar()
>>> bar2 = Bar()
>>> bar1.num = 2
>>> bar2.num
1
>>> Bar.num = 3
>>> bar2.num
3
>>> bar1.num
2
>>> bar1.__class__.num
3
Rzeczywista odpowiedź
Jeśli nie potrzebuję zmiennej klasy, ale wystarczy ustawić wartość domyślną dla moich zmiennych instancji, czy obie metody są równie dobre? A może jeden z nich bardziej „pytoniczny” niż drugi?
Kod na wystawie B jest po prostu nieprawidłowy: dlaczego miałbyś chcieć wiązać atrybut klasy (wartość domyślna przy tworzeniu instancji) z pojedynczą instancją?
Kod w eksponacie A jest w porządku.
Jeśli chcesz podać wartości domyślne dla zmiennych instancji w swoim konstruktorze, zrobiłbym to jednak:
class Foo:
def __init__(self, num = None):
self.num = num if num is not None else 1
...lub nawet:
class Foo:
DEFAULT_NUM = 1
def __init__(self, num = None):
self.num = num if num is not None else DEFAULT_NUM
... lub nawet: (preferowane, ale wtedy i tylko wtedy, gdy masz do czynienia z typami niezmiennymi!)
class Foo:
def __init__(self, num = 1):
self.num = num
W ten sposób możesz:
foo1 = Foo(4)
foo2 = Foo()
self.attr = attr or []
w ramach__init__
metody. Osiąga ten sam rezultat (tak mi się wydaje) i nadal jest jasny i czytelny.