In Python 3.4+, perché dovrei usare namedtuple su SimpleNamespace quando non uso dict, sembrano molto simili


11

Ad un certo punto potresti scoprire funzioni con molti argomenti. A volte ha senso combinare alcuni degli argomenti in superargomenti. L'ho fatto spesso con dicts, ma ora sto cercando modi migliori per farlo.

Vorrei girare ...

def do_something(ax, ay, az, bu, bv, c):
    # Do something

... in ...

def do_something(a, b, c):
    # Do something

... dove ae bcontengono le loro subvariazioni.

Un modo per farlo è fare:

A = namedtuple('A', 'x, y, z')
a = A(ax, ay, az)
B = namedtuple('B', 'u, v')
b = B(bu, bv)

Tuttavia, questo sembra più semplice:

a = SimpleNamespace(x=ax, y=ay, z=az)
b = SimpleNamespace(u=bu, v=bv)

Qual è lo svantaggio? Il fatto che ae bnon sono ben scritti? Non sono oggetti A e B?

(A proposito, non preoccuparti per i nomi delle variabili. Normalmente non uso come nomi di variabili brevi.)


1
Non ci sono inconvenienti di per sé, sono solo cose diverse. Per cominciare i nomi delle coppie sono immutabili mentre gli spazi dei nomi sono mutabili. La mutevole è migliore o peggiore di immutabile? Dipende da ciò di cui hai bisogno o desideri, in molti casi non importa. La tua funzione probabilmente funzionerebbe con qualsiasi oggetto con gli attributi richiesti, come costruirlo dipende dal chiamante.
Smetti di fare del male a Monica

@Goyo Grazie. La cosa "svantaggio" era un modo goffo di dirlo. Non intendevo implicare che uno fosse intrinsecamente migliore dell'altro. Volevo solo i pro e i contro. Grazie ancora.
André Christoffer Andersen,

1
la quarta riga non dovrebbe apparire come "b = B (bu, bv)"?
Alen Siljak,

@AlenSiljak Sì, dovrebbe. Lo riparerò ora.
André Christoffer Andersen,

Risposte:


21

SimpleNamespaceè fondamentalmente solo una bella facciata in cima a un dizionario. Ti consente di utilizzare le proprietà anziché le chiavi di indice. Questo è bello in quanto è super flessibile e facile da manipolare.

L'aspetto negativo di quella flessibilità è che non fornisce alcuna struttura. Non c'è nulla che impedisca a qualcuno di chiamare SimpleNamespace(x=ax, y=ay)(e del a.zad un certo punto in seguito). Se questa istanza viene passata alla funzione, l'eccezione si verifica quando si tenta di accedere al campo.

Al contrario, namedtupleti consente di creare un tipo strutturato. Il tipo avrà un nome e saprà quali campi dovrebbe avere. Non sarai in grado di creare un'istanza senza ciascuno di quei campi e non potranno essere rimossi in seguito. Inoltre, l'istanza è immutabile, quindi saprai che il valore in a.xsarà sempre lo stesso.

Sta a te decidere se hai bisogno della flessibilità che SimpleNamespaceti offre o se preferisci avere la struttura e le garanzie fornite da namedtuple.


2

Mi piace molto la risposta su strutturato contro no, quindi sto solo fornendo un esempio concreto di seguito.

SimpleNamespaceaccetterà le chiavi che iniziano con _. Se stai cercando un modo semplice e veloce per trasformare, per esempio, JSON che non controlli in oggetti con nomi di campo, questo è molto utile:

d = {"_id": 2342122, "text": "hi there!"} # Elasticsearch gives this id!
e = SimpleNamespace(**d) # works
Name = namedtuple("Name", sorted(d)) # ValueError so we can't do Name(**d)

Nota sopra che puoi vedere che namedtupleci dà un intero oggetto in più che SimpleNamespacenon lo farà mai. Ognuno SimpleNamespaceè davvero un "fiocco di neve unico", mentre namedtupleesiste senza essere mai istanziato con alcun valore concreto. Ovunque tu abbia bisogno di astrazioni che si generalizzano su valori concreti, probabilmente dovresti preferirlo.


1

Riassunto di SimpleNamespace

Permette di inizializzare gli attributi durante la costruzione dell'oggetto:

sn = SimpleNamespace(a=1, b=2)

Fornisce un leggibile

repr(): eval(repr(sn)) == sn

Sostituisce il confronto predefinito. Invece di confrontare per id(), confronta invece i valori degli attributi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.