Come di Python 3.6, the keyword argument order is preserved. Prima di 3.6, non è possibile poiché lo OrderedDict
diventa trasformato in dict
.
La prima cosa da capire è che il valore si passa **example
non diventa automaticamente il valore in **kwargs
. Considerate questo caso, in cui kwargs
avrà solo una parte del example
:
def f(a, **kwargs):
pass
example = {'a': 1, 'b': 2}
f(**example)
O questo caso, in cui avrà più valori di quelli nell'esempio:
example = {'b': 2}
f(a=1, c=3, **example)
O ancora alcuna sovrapposizione a tutti:
example = {'a': 1}
f(b=2, **example)
Quindi, quello che stai chiedendo perché non ha molto senso.
Eppure, potrebbe essere bello se ci fosse un modo per specificare che si desidera una ordinata **kwargs
, non importa dove le parole chiave provenivano da-espliciti args parole chiave nell'ordine in cui appaiono, seguito da tutti gli elementi di **example
nell'ordine in cui appaiono in example
(che potrebbe essere arbitrario se example
fosse un dict
, ma potrebbe anche essere significativo se fosse un OrderedDict
).
Definire tutti i dettagli complessi e mantenere le prestazioni accettabili risulta essere più difficile di quanto sembri. Vedi PEP 468 e i thread collegati, per qualche discussione sull'idea. Sembra essersi fermato questa volta, ma se qualcuno lo raccoglie e lo sostiene (e scrive un'implementazione di riferimento per le persone con cui giocare, il che dipende da un OrderedDict
accessibile dall'API C, ma che spero ci sia tra 3.5 e più), Sospetto che alla fine entrerà nella lingua.
A proposito, si noti che se questo fosse possibile, sarebbe quasi certamente essere utilizzato nel costruttore per OrderedDict
sé. Ma se si prova che, tutto quello che stai facendo è il congelamento qualche ordine arbitrario come ordine permanente:
>>> d = OrderedDict(a=1, b=2, c=3)
OrderedDict([('a', 1), ('c', 3), ('b', 2)])
Nel frattempo, quali opzioni avete?
Ebbene, l'opzione più ovvia è solo per passare example
come un normale argomento, invece di disimballaggio:
def f(example):
pass
example = OrderedDict([('a', 1), ('b', 2)])
f(example)
O, naturalmente, è possibile utilizzare *args
e trasmettere gli articoli come tuple, ma questo è generalmente più brutta .
Potrebbero esserci altre soluzioni alternative nei thread collegati dal PEP, ma in realtà nessuno di questi sarà migliore di questo. (Ad eccezione di ... IIRC, Li Haoyi ha escogitato una soluzione basata sul suo MacroPy per passare gli argomenti delle parole chiave di conservazione degli ordini, ma non ricordo i dettagli. Le soluzioni MacroPy in generale sono fantastiche se sei disposto ad usare MacroPy e scrivere codice che non è abbastanza leggibile come Python, ma non è sempre appropriato ...)
Grazie per le risposte dettagliate. Quello che ho finito per fare è stato permettere un primo argomento opzionale (un ditt ordinato) che sarebbe stato usato preferibilmente con i ** kwargs se forniti. Ottime informazioni, anche se – theodox
** Vedi anche: ** https://duckduckgo.com/?q=pep468 – dreftymac