W pewnym momencie możesz natrafić na funkcje z wieloma argumentami. Czasami sensowne jest łączenie niektórych argumentów w superargumenty. Często robiłem to z dyktando, ale teraz szukam lepszych sposobów na zrobienie tego.
Chciałbym włączyć ...
def do_something(ax, ay, az, bu, bv, c):
# Do something
... w ...
def do_something(a, b, c):
# Do something
... gdzie a
i b
zawierają ich podwariacje.
Jednym ze sposobów na to jest:
A = namedtuple('A', 'x, y, z')
a = A(ax, ay, az)
B = namedtuple('B', 'u, v')
b = B(bu, bv)
Wydaje się to jednak prostsze:
a = SimpleNamespace(x=ax, y=ay, z=az)
b = SimpleNamespace(u=bu, v=bv)
Jaka jest wada? Fakt, że a
i b
nie są dobrze napisane? To nie są obiekty A i B?
(Przy okazji, nie przejmuj się nazwami zmiennych. Zwykle nie używam jako krótkich nazw zmiennych).
python
variables
dictionary
André Christoffer Andersen
źródło
źródło
Odpowiedzi:
SimpleNamespace
jest po prostu ładną fasadą na górze słownika. Pozwala używać właściwości zamiast kluczy indeksu. Jest to miłe, ponieważ jest bardzo elastyczne i łatwe w obsłudze.Minusem tej elastyczności jest to, że nie zapewnia żadnej struktury. Nic nie stoi na przeszkodzie, aby ktoś zadzwonił
SimpleNamespace(x=ax, y=ay)
(idel a.z
w pewnym momencie później). Jeśli to wystąpienie zostanie przekazane do funkcji, wyjątek występuje podczas próby uzyskania dostępu do pola.Natomiast
namedtuple
pozwala utworzyć typ strukturalny. Typ będzie miał nazwę i będzie wiedział, jakie pola powinien mieć. Nie będziesz w stanie utworzyć instancji bez każdego z tych pól i nie będzie można ich później usunąć. Ponadto instancja jest niezmienna, więc będziesz wiedział, że wartość wa.x
będzie zawsze taka sama.To Ty decydujesz, czy potrzebujesz elastyczności, która
SimpleNamespace
Ci daje, czy wolisz mieć strukturę i gwarancjenamedtuple
.źródło
Bardzo podoba mi się odpowiedź na temat strukturyzowanej kontra nie, dlatego poniżej podam konkretny przykład.
SimpleNamespace
zaakceptuje klucze zaczynające się od_
. Jeśli szukasz szybkiego i łatwego sposobu na przekształcenie, powiedzmy JSON, którego nie kontrolujesz w obiekty o nazwach pól, jest to bardzo przydatne:Zauważ powyżej, że widać, że
namedtuple
daje nam to cały dodatkowy obiekt, którySimpleNamespace
nigdy nie będzie. Każda z nichSimpleNamespace
jest naprawdę „wyjątkowym płatkiem śniegu”, podczas gdynamedtuple
istnieje bez tworzenia konkretnych wartości. Gdziekolwiek potrzebujesz abstrakcji, które uogólniają na konkretne wartości, prawdopodobnie powinieneś je preferować.źródło
Podsumowanie
SimpleNamespace
Pozwala na inicjalizację atrybutów podczas konstruowania obiektu:
Zapewnia czytelność
Zastępuje domyślne porównanie. Zamiast porównywać według
id()
, porównuje wartości atrybutów.źródło