3366 Stimmen

Was bewirken ** (Doppelstern/Ostern) und * (Stern/Ostern) bei Parametern?

Was tun *args y **kwargs bedeuten?

def foo(x, y, *args):
def bar(x, y, **kwargs):

14 Stimmen

161 Stimmen

Diese Frage ist ein sehr beliebtes Ziel für Duplikate, aber leider wird sie oft falsch verwendet. Denken Sie daran, dass diese Frage nach folgenden Punkten fragt Funktionen mit Varargs definieren ( def func(*args) ). Für die Frage, was es in der Funktion bedeutet ruft auf. ( func(*[1,2]) ) siehe aquí . Bei einer Frage, die comment zum Entpacken von Argumentlisten siehe aquí . Für eine Frage, die fragt, was die * bedeutet in Literale ( [*[1, 2]] ) siehe aquí .

4 Stimmen

@Aran-Fey: Ich denke, ein besseres Ziel für "was bedeutet es in Funktionsaufrufen" ist Was bedeutet der Sternoperator in einem Funktionsaufruf? . Ihr Link geht nicht wirklich auf die Verwendung von ** und es ist eine viel engere Frage.

47voto

Brad Solomon Punkte 33623

Diese Tabelle ist praktisch für die Verwendung von * y ** in Funktion Konstruktion und Funktion aufrufen :

            In function construction         In function call
=======================================================================
          |  def f(*args):                 |  def f(a, b):
*args     |      for arg in args:          |      return a + b
          |          print(arg)            |  args = (1, 2)
          |  f(1, 2)                       |  f(*args)
----------|--------------------------------|---------------------------
          |  def f(a, b):                  |  def f(a, b):
**kwargs  |      return a + b              |      return a + b
          |  def g(**kwargs):              |  kwargs = dict(a=1, b=2)
          |      return f(**kwargs)        |  f(**kwargs)
          |  g(a=1, b=2)                   |
-----------------------------------------------------------------------

Dies ist eigentlich nur eine Zusammenfassung von Lorin Hochsteins Antwort aber ich finde es hilfreich.

In diesem Zusammenhang: Verwendungen für die Stern/Splat-Operatoren sind erweitert in Python 3

36voto

Meysam Sadeghi Punkte 988

TL;DR

Im Folgenden finden Sie 6 verschiedene Anwendungsfälle für * y ** in der Python-Programmierung:

  1. *Zur Annahme einer beliebigen Anzahl von Positionsargumenten mit `args:**def foo(*args): pass, hierfooakzeptiert eine beliebige Anzahl von Positionsargumenten, d. h., die folgenden Aufrufe sind gültigfoo(1),foo(1, 'bar')`
  2. Um eine beliebige Anzahl von Schlüsselwortargumenten zu akzeptieren, verwenden Sie `kwargs:**def foo(**kwargs): passHier akzeptiert "foo" eine beliebige Anzahl von Schlüsselwortargumenten, d. h., die folgenden Aufrufe sind gültigfoo(name='Tom'),foo(name='Tom', age=33)`
  3. Zur Annahme einer beliebigen Anzahl von Positions- und Schlüsselwortargumenten mit *args, **kwargs :* `def foo(args, kwargs): pass, hierfooakzeptiert eine beliebige Anzahl von Positions- und Schlüsselwortargumenten, d. h., die folgenden Aufrufe sind gültigfoo(1,name='Tom'),foo(1, 'bar', name='Tom', age=33)`
  4. *Um nur Schlüsselwortargumente zu erzwingen, verwenden Sie `:**def foo(pos1, pos2, , kwarg1): pass, hierbedeutet, dass foo nur Schlüsselwortargumente nach pos2 akzeptiert, alsofoo(1, 2, 3)löst TypeError aus, aberfoo(1, 2, kwarg1=3)` ist in Ordnung.
  5. *kein weiteres Interesse an weiteren Argumenten zur Positionierung zu bekunden mit `(Hinweis: Dies ist nur eine Konvention):**def foo(bar, baz, *): passbedeutet (durch Konvention)fooverwendet nurbarybaz` Argumente in ihre Arbeit einfließen und andere ignoriert werden.
  6. kein weiteres Interesse an weiteren Schlüsselwortargumenten zu bekunden mit `\(Hinweis: Dies ist nur eine Konvention):**def foo(bar, baz, **): passbedeutet (durch Konvention)fooverwendet nurbarybaz` Argumente in ihre Arbeit einfließen und andere ignoriert werden.

BONUS: Ab Python 3.8 kann man mit / in der Funktionsdefinition, um nur positionale Parameter zu erzwingen. Im folgenden Beispiel sind die Parameter a und b Nur für die Position , während c oder d Positionsangaben oder Schlüsselwörter sein können, und e oder f müssen Schlüsselwörter sein:

def f(a, b, /, c, d, *, e, f):
    pass

31voto

ronak Punkte 1588

* y ** haben eine besondere Verwendung in der Argumentliste der Funktion. * impliziert, dass das Argument eine Liste ist und ** impliziert, dass das Argument ein Wörterbuch ist. Dies erlaubt es Funktionen, eine beliebige Anzahl von Argumente

26voto

Miladiouss Punkte 3372

Für diejenigen unter Ihnen, die an Beispielen lernen!

  1. Der Zweck der * ist es, Ihnen die Möglichkeit zu geben, eine Funktion zu definieren, die eine beliebige Anzahl von Argumenten in Form einer Liste annehmen kann (z. B. f(*myList) ).
  2. Der Zweck der ** ist es, Ihnen die Möglichkeit zu geben, die Argumente einer Funktion durch die Bereitstellung eines Wörterbuchs (z.B. f(**{'x' : 1, 'y' : 2}) ).

Wir zeigen dies, indem wir eine Funktion definieren, die zwei normale Variablen annimmt x , y und kann weitere Argumente akzeptieren als myArgs und kann noch mehr Argumente akzeptieren als myKW . Später werden wir zeigen, wie man y mit myArgDict .

def f(x, y, *myArgs, **myKW):
    print("# x      = {}".format(x))
    print("# y      = {}".format(y))
    print("# myArgs = {}".format(myArgs))
    print("# myKW   = {}".format(myKW))
    print("# ----------------------------------------------------------------------")

# Define a list for demonstration purposes
myList    = ["Left", "Right", "Up", "Down"]
# Define a dictionary for demonstration purposes
myDict    = {"Wubba": "lubba", "Dub": "dub"}
# Define a dictionary to feed y
myArgDict = {'y': "Why?", 'y0': "Why not?", "q": "Here is a cue!"}

# The 1st elem of myList feeds y
f("myEx", *myList, **myDict)
# x      = myEx
# y      = Left
# myArgs = ('Right', 'Up', 'Down')
# myKW   = {'Wubba': 'lubba', 'Dub': 'dub'}
# ----------------------------------------------------------------------

# y is matched and fed first
# The rest of myArgDict becomes additional arguments feeding myKW
f("myEx", **myArgDict)
# x      = myEx
# y      = Why?
# myArgs = ()
# myKW   = {'y0': 'Why not?', 'q': 'Here is a cue!'}
# ----------------------------------------------------------------------

# The rest of myArgDict becomes additional arguments feeding myArgs
f("myEx", *myArgDict)
# x      = myEx
# y      = y
# myArgs = ('y0', 'q')
# myKW   = {}
# ----------------------------------------------------------------------

# Feed extra arguments manually and append even more from my list
f("myEx", 4, 42, 420, *myList, *myDict, **myDict)
# x      = myEx
# y      = 4
# myArgs = (42, 420, 'Left', 'Right', 'Up', 'Down', 'Wubba', 'Dub')
# myKW   = {'Wubba': 'lubba', 'Dub': 'dub'}
# ----------------------------------------------------------------------

# Without the stars, the entire provided list and dict become x, and y:
f(myList, myDict)
# x      = ['Left', 'Right', 'Up', 'Down']
# y      = {'Wubba': 'lubba', 'Dub': 'dub'}
# myArgs = ()
# myKW   = {}
# ----------------------------------------------------------------------

Vorbehalte

  1. ** ist ausschließlich für Wörterbücher reserviert.
  2. Die Zuweisung nicht-optionaler Argumente erfolgt zuerst.
  3. Sie können ein nicht-optionales Argument nicht zweimal verwenden.
  4. Falls zutreffend, ** muss nach * immer.

22voto

Chris Upchurch Punkte 14893

Aus der Python-Dokumentation:

Wenn es mehr Positionsargumente als formale Parametersteckplätze gibt, wird eine TypeError-Ausnahme ausgelöst, es sei denn, es ist ein formaler Parameter mit der Syntax "*identifier" vorhanden; in diesem Fall erhält dieser formale Parameter ein Tupel, das die überzähligen Positionsargumente enthält (oder ein leeres Tupel, wenn es keine überzähligen Positionsargumente gab).

Wenn ein Schlüsselwortargument keinem formalen Parameternamen entspricht, wird eine TypeError-Ausnahme ausgelöst, es sei denn, es ist ein formaler Parameter mit der Syntax "**identifier" vorhanden; in diesem Fall erhält dieser formale Parameter ein Wörterbuch mit den überzähligen Schlüsselwortargumenten (unter Verwendung der Schlüsselwörter als Schlüssel und der Argumentwerte als entsprechende Werte) oder ein (neues) leeres Wörterbuch, wenn keine überzähligen Schlüsselwortargumente vorhanden waren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X