Jak nazywa się ** w python?


59

Podczas programowania Python czasami robię a, **aby dokonać konwersji. Rozumiem, co robi, ale jakie struktury danych modyfikuję? A dicta co innego? An array? Czy istnieje nazwa dla **operatora?


3
operator wykładniczy?
Rook

12
Istnieją dwa znaczenia **. Moc i „słownik argumentów słów kluczowych”. O czym ty mówisz Dokumentacja zawiera następujące słowa: „Jeśli obecny jest formularz„ ** identyfikator ”, jest on inicjowany w nowym słowniku, otrzymując nadmiar argumentów słów kluczowych, domyślnie w nowym pustym słowniku.” Które z nich wydają się odpowiednie dla twojego pytania?
S.Lott,

„Słownik argumentów słów kluczowych” był tym, o który pytam. Dziękuję za komentarze.
Niklas Rosencrantz

Odpowiedzi:


86

Nie jest to jako taki operator, więc tak naprawdę nie ma nazwy, ale jest zdefiniowany jako „reguła składniowa” . Więc powinno się to nazywać:

  • „Składnia rozpakowywania argumentu słowa kluczowego”

Jeśli masz listę argumentów *args, to się nazywa „rozpakowanie argument” , w taki sam sposób **kwargsnazywany jest „argumentem kluczowe rozpakowaniu” .

Jeśli użyjesz go po lewej stronie =, jak w a, *middle, end = my_tuple, powiesz „rozpakowanie krotki” .

W sumie istnieją trzy typy argumentów (jednoparametrowych):

def f(x)  # x: positional argument
def f(x, y=0)  # y: keyword argument
def f(x, *xs, y=0)  # y: keyword-only argument

*argsArgumentem nazywany jest „zmienny parametr pozycyjny” i **kwargsjest „zmienny parametr słowo kluczowe”. Argumenty zawierające tylko słowa kluczowe nie mogą być podawane pozycyjnie, ponieważ zmienny parametr pozycyjny przyjmuje wszystkie przekazywane argumenty.

Większość z nich można znaleźć w dokumentach PEP 0362 i 3102 , a także w sekcji kontroli przepływu dokumentów. Należy jednak zauważyć, że obiekt podpisu funkcji PEP to tylko szkic, a terminologia może być tylko pomysłem jednej osoby. Ale i tak są to dobre warunki. :)

Zatem argumenty *i **po prostu rozpakowują swoje odpowiednie struktury danych:

args = (1, 2, 3)  # usually a tuple, always an iterable[1]

f(*args)  f(1, 2, 3)

# and 

kwargs = {"a": 1, "b": 2, "c": 3}  # usually a dict, always a mapping*

f(**kwargs) -> f(a=1, b=2, c=3)

[1]: Iterables to obiekty, które implementują __iter__()metodę, a mapowania to obiekty, które implementują keys()i __getitem__(). Każdy obiekt, który obsługuje protokół ten należy rozumieć przez konstruktorów tuple()i dict(), dlatego mogą być stosowane do rozpakowywania argumentów.


3
Jeśli ktoś jest zdezorientowany, def f(x, *xs, y=0): passnie jest poprawna składnia Pythona 2. {5,6,7}, ani nie def f(x, y=0, *xs):robi tego, czego można się spodziewać. AFAIK, jedynym sposobem na osiągnięcie (oczywiście) zamierzonego efektu jest def f(x, *xs, **kw): y=kw.get('y', 0); del kw; .... Python 3 obsługuje oryginalną składnię zgodnie z oczekiwaniami.
chbrown

1
Skoro już o tym begin, *middle, end = (0, 1, 2, 3, 4, 5)mowa : składnia również nie działa w Pythonie 2.x.
Stefano Palazzo

Ta odpowiedź jest niepoprawna w Pythonie 3.5 i nowszych. PEP-448 określa ** operatora jako operatora rozpakowywania słownika. Zobacz python.org/dev/peps/pep-0448
devnul3

13

Nie sądzę, żeby to miało nazwę. W Python Docs w sekcji „Rozpakowywanie list argumentów” jest to po prostu nazywane „ **operatorem”.

Nie jestem pewien, co rozumiesz przez „drugą” strukturę danych. Kiedy to zrobisz f(**kwargs), rozpakujesz słownik kwargsjako sekwencję par klucz-wartość. Nie widzę w tym żadnej innej struktury.

Będę skopiować przykład w powyższej dokumentacji dla jasności.

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print "-- This parrot wouldn't", action,
...     print "if you put", voltage, "volts through it.",
...     print "E's", state, "!"
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

Zobacz także: Co oznaczają * args i ** kwargs?


Istnieje kilka możliwych sposobów, w jaki czytelnik może zinterpretować f(**kwargs)...
Deer Hunter,

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.