As Pythona 3.6, the keyword argument order is preserved. Przed 3.6 nie jest to możliwe, ponieważ OrderedDict
zamienia się w dict
.
Pierwszą rzeczą, aby zdać sobie sprawę, że wartość przechodzą w **example
nie stają się automatycznie wartością w **kwargs
. Rozważmy następujący przypadek, gdzie kwargs
będzie miał tylko część example
:
def f(a, **kwargs):
pass
example = {'a': 1, 'b': 2}
f(**example)
Albo to przypadek, gdzie będzie mieć więcej wartości niż w przykładzie:
example = {'b': 2}
f(a=1, c=3, **example)
lub nawet bez nakładania na wszystkich:
example = {'a': 1}
f(b=2, **example)
Więc co pytasz o tak naprawdę nie ma sensu.
Mimo to może być miło, gdyby był jakiś sposób, aby określić, że ma uporządkowaną **kwargs
, nieważne gdzie słowa kluczowe pochodziła z-wyraźnych args słowo kluczowe w kolejności ich występowania, a następnie wszystkie pozycje **example
w kolejności, w jakiej pojawiają się w example
(które mogą być dowolne, jeśli example
były dict
, ale mogą być również znaczące, jeśli były to OrderedDict
).
Definiowanie wszystkich skomplikowanych szczegółów i utrzymywanie wydajności do zaakceptowania okazuje się trudniejsze niż się wydaje. Zobacz PEP 468 i powiązane wątki, aby porozmawiać na ten temat. Wygląda na to, że tym razem zawiesiło się, ale jeśli ktoś je podniesie i poprowadzi mistrzostwo (i zapisze referencyjną implementację dla ludzi, z którymi można grać), co zależy od OrderedDict
dostępnej z C API, ale mam nadzieję, że będzie tam w wersji 3.5+), Podejrzewam, że w końcu dotrze do tego języka.
Nawiasem mówiąc, należy pamiętać, że jeśli ten były możliwe, to prawie na pewno być używany w konstruktorze dla samej OrderedDict
. Ale jeśli spróbujesz, że wszystko robisz jest zamrożenie trochę dowolnej kolejności jako stałej kolejności:
>>> d = OrderedDict(a=1, b=2, c=3)
OrderedDict([('a', 1), ('c', 3), ('b', 2)])
Tymczasem, jakie opcje masz?
Cóż, oczywistym rozwiązaniem jest po prostu przejść example
jako normalny argumentu zamiast rozpakowaniu go:
def f(example):
pass
example = OrderedDict([('a', 1), ('b', 2)])
f(example)
lub, oczywiście, można użyć *args
i przekazać przedmioty jak krotki, ale to ogólnie brzydsze .
Możliwe są inne sposoby obejścia wątków powiązanych z PEP, ale tak naprawdę żadna z nich nie będzie lepsza. (Z wyjątkiem ... IIRC, Li Haoyi wymyślił rozwiązanie oparte na jego MacroPy w celu przekazania argumentów słów kluczowych zachowujących porządek, ale nie pamiętam szczegółów.Opcje MacroPy są generalnie świetne, jeśli chcesz używać MacroPy i pisać kod to nie całkiem czyta się jak Python, ale to nie zawsze jest odpowiednie ...)
Dzięki za szczegółowe odpowiedzi. W końcu udało mi się zezwolić na opcjonalny pierwszy argument (uporządkowany dyktat), który byłby użyty przed dodaniem ** kwargów, jeśli taki był. Świetne informacje, chociaż – theodox
** Zobacz też: ** https://duckduckgo.com/?q=pep468 – dreftymac