Frage

Was bewirkt in den folgenden Methodendefinitionen die * Und ** tun für param2?

def foo(param1, *param2):
def bar(param1, **param2):
War es hilfreich?

Lösung

Der *args Und **kwargs ist eine gebräuchliche Redewendung, um eine beliebige Anzahl von Argumenten für Funktionen zuzulassen, wie im Abschnitt beschrieben mehr zum Definieren von Funktionen in der Python-Dokumentation.

Der *args gibt Ihnen alle Funktionsparameter als Tupel:

In [1]: def foo(*args):
   ...:     for a in args:
   ...:         print a
   ...:         
   ...:         

In [2]: foo(1)
1


In [4]: foo(1,2,3)
1
2
3

Der **kwargs werde dir alles gebenSchlüsselwortargumente mit Ausnahme derjenigen, die einem formalen Parameter als Wörterbuch entsprechen.

In [5]: def bar(**kwargs):
   ...:     for a in kwargs:
   ...:         print a, kwargs[a]
   ...:         
   ...:         

In [6]: bar(name='one', age=27)
age 27
name one

Beide Redewendungen können mit normalen Argumenten gemischt werden, um eine Reihe fester und einige variable Argumente zu ermöglichen:

def foo(kind, *args, **kwargs):
   pass

Eine andere Verwendung von *l Redewendung ist zu Argumentlisten entpacken beim Aufruf einer Funktion.

In [9]: def foo(bar, lee):
   ...:     print bar, lee
   ...:     
   ...:     

In [10]: l = [1,2]

In [11]: foo(*l)
1 2

In Python 3 ist die Verwendung möglich *l auf der linken Seite einer Aufgabe (Erweitertes iterierbares Entpacken), obwohl es in diesem Zusammenhang eine Liste anstelle eines Tupels gibt:

first, *rest = [1,2,3,4]
first, *l, last = [1,2,3,4]

Außerdem fügt Python 3 eine neue Semantik hinzu (siehe PEP 3102):

def func(arg1, arg2, arg3, *, kwarg1, kwarg2):
    pass

Eine solche Funktion akzeptiert nur 3 Positionsargumente und alles danach * können nur als Schlüsselwortargumente übergeben werden.

Andere Tipps

Es ist auch erwähnenswert, dass Sie es verwenden können * Und ** auch beim Aufrufen von Funktionen.Dies ist eine Abkürzung, die es Ihnen ermöglicht, mehrere Argumente direkt über eine Liste/ein Tupel oder ein Wörterbuch an eine Funktion zu übergeben.Wenn Sie beispielsweise die folgende Funktion haben:

def foo(x,y,z):
    print("x=" + str(x))
    print("y=" + str(y))
    print("z=" + str(z))

Sie können Dinge tun wie:

>>> mylist = [1,2,3]
>>> foo(*mylist)
x=1
y=2
z=3

>>> mydict = {'x':1,'y':2,'z':3}
>>> foo(**mydict)
x=1
y=2
z=3

>>> mytuple = (1, 2, 3)
>>> foo(*mytuple)
x=1
y=2
z=3

Notiz:Die Schlüssel rein mydict müssen genauso benannt werden wie die Parameter einer Funktion foo.Andernfalls wird ein ausgelöst TypeError:

>>> mydict = {'x':1,'y':2,'z':3,'badnews':9}
>>> foo(**mydict)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() got an unexpected keyword argument 'badnews'

Das einzelne * bedeutet, dass es beliebig viele zusätzliche Positionsargumente geben kann. foo() kann aufgerufen werden wie foo(1,2,3,4,5).Im Hauptteil von foo() param2 befindet sich eine Sequenz, die 2-5 enthält.

Das doppelte ** bedeutet, dass es beliebig viele zusätzliche benannte Parameter geben kann. bar() kann aufgerufen werden wie bar(1, a=2, b=3).Im Hauptteil von bar() ist param2 ein Wörterbuch, das {'a':2, 'b':3 } enthält.

Mit folgendem Code:

def foo(param1, *param2):
    print(param1)
    print(param2)

def bar(param1, **param2):
    print(param1)
    print(param2)

foo(1,2,3,4,5)
bar(1,a=2,b=3)

Die Ausgabe ist

1
(2, 3, 4, 5)
1
{'a': 2, 'b': 3}

Was macht ** (Doppelstern) und * (Stern) für Parameter

Sie erlauben Zu definierende Funktionen, die akzeptiert werden sollen und für Benutzer zu passieren beliebig viele Argumente, Positionsargumente (*) und Schlüsselwort (**).

Funktionen definieren

*args ermöglicht eine beliebige Anzahl optionaler Positionsargumente (Parameter), die einem Tupel mit dem Namen zugewiesen werden args.

**kwargs ermöglicht eine beliebige Anzahl optionaler Schlüsselwortargumente (Parameter), die in einem Diktat mit dem Namen enthalten sein werden kwargs.

Sie können (und sollten) jeden geeigneten Namen wählen, aber wenn die Argumente eine unspezifische Semantik haben sollen, args Und kwargs sind Standardnamen.

Erweiterung, Übergabe einer beliebigen Anzahl von Argumenten

Sie können auch verwenden *args Und **kwargs um Parameter aus Listen (oder beliebigen iterierbaren Elementen) bzw. Diktaten (oder beliebigen Zuordnungen) zu übergeben.

Die Funktion, die die Parameter empfängt, muss nicht wissen, dass sie erweitert werden.

Beispielsweise erwartet xrange in Python 2 dies nicht explizit *args, aber da es 3 ganze Zahlen als Argumente benötigt:

>>> x = xrange(3) # create our *args - an iterable of 3 integers
>>> xrange(*x)    # expand here
xrange(0, 2, 2)

Als weiteres Beispiel können wir die Diktaterweiterung verwenden str.format:

>>> foo = 'FOO'
>>> bar = 'BAR'
>>> 'this is foo, {foo} and bar, {bar}'.format(**locals())
'this is foo, FOO and bar, BAR'

Neu in Python 3:Definieren von Funktionen mit Nur-Schlüsselwort-Argumenten

Du kannst haben Nur Schlüsselwortargumente nach dem *args - zum Beispiel hier, kwarg2 muss als Schlüsselwortargument angegeben werden – nicht positionell:

def foo(arg, kwarg=None, *args, kwarg2=None, **kwargs): 
    return arg, kwarg, args, kwarg2, kwargs

Verwendung:

>>> foo(1,2,3,4,5,kwarg2='kwarg2', bar='bar', baz='baz')
(1, 2, (3, 4, 5), 'kwarg2', {'bar': 'bar', 'baz': 'baz'})

Auch, * kann allein verwendet werden, um anzugeben, dass nur Schlüsselwortargumente folgen, ohne unbegrenzte Positionsargumente zuzulassen.

def foo(arg, kwarg=None, *, kwarg2=None, **kwargs): 
    return arg, kwarg, kwarg2, kwargs

Hier, kwarg2 Auch hier muss es sich um ein explizit benanntes Schlüsselwortargument handeln:

>>> foo(1,2,kwarg2='kwarg2', foo='foo', bar='bar')
(1, 2, 'kwarg2', {'foo': 'foo', 'bar': 'bar'})

Und wir können keine unbegrenzten Positionsargumente mehr akzeptieren, weil wir keine haben *args*:

>>> foo(1,2,3,4,5, kwarg2='kwarg2', foo='foo', bar='bar')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() takes from 1 to 2 positional arguments 
    but 5 positional arguments (and 1 keyword-only argument) were given

Nochmals einfacher: Hier benötigen wir kwarg namentlich, nicht positionell anzugeben:

def bar(*, kwarg=None): 
    return kwarg

In diesem Beispiel sehen wir das, wenn wir versuchen zu passen kwarg positionell erhalten wir eine Fehlermeldung:

>>> bar('kwarg')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bar() takes 0 positional arguments but 1 was given

Wir müssen das explizit übergeben kwarg Parameter als Schlüsselwortargument.

>>> bar(kwarg='kwarg')
'kwarg'

Python 2-kompatible Demos

*args (normalerweise „Sternargumente“ genannt) und **kwargs (Sterne können durch „Kwargs“ impliziert werden, seien Sie jedoch explizit durch „Doppelstern-Kwargs“ gekennzeichnet.) sind gängige Redewendungen von Python für die Verwendung von * Und ** Notation.Diese spezifischen Variablennamen sind nicht erforderlich (z. B.Du könntest benutzen *foos Und **bars), aber eine Abweichung von der Konvention wird Ihre Python-Programmiererkollegen wahrscheinlich verärgern.

Wir verwenden diese normalerweise, wenn wir nicht wissen, was unsere Funktion empfangen wird oder wie viele Argumente wir möglicherweise übergeben, und manchmal, selbst wenn die separate Benennung jeder Variablen sehr chaotisch und überflüssig wäre (aber dies ist ein Fall, in dem normalerweise explizit angegeben wird). besser als implizit).

Beispiel 1

Die folgende Funktion beschreibt, wie sie verwendet werden können, und demonstriert ihr Verhalten.Beachten Sie den Namen b Das Argument wird vom zweiten Positionsargument verbraucht, bevor:

def foo(a, b=10, *args, **kwargs):
    '''
    this function takes required argument a, not required keyword argument b
    and any number of unknown positional arguments and keyword arguments after
    '''
    print('a is a required argument, and its value is {0}'.format(a))
    print('b not required, its default value is 10, actual value: {0}'.format(b))
    # we can inspect the unknown arguments we were passed:
    #  - args:
    print('args is of type {0} and length {1}'.format(type(args), len(args)))
    for arg in args:
        print('unknown arg: {0}'.format(arg))
    #  - kwargs:
    print('kwargs is of type {0} and length {1}'.format(type(kwargs),
                                                        len(kwargs)))
    for kw, arg in kwargs.items():
        print('unknown kwarg - kw: {0}, arg: {1}'.format(kw, arg))
    # But we don't have to know anything about them 
    # to pass them to other functions.
    print('Args or kwargs can be passed without knowing what they are.')
    # max can take two or more positional args: max(a, b, c...)
    print('e.g. max(a, b, *args) \n{0}'.format(
      max(a, b, *args))) 
    kweg = 'dict({0})'.format( # named args same as unknown kwargs
      ', '.join('{k}={v}'.format(k=k, v=v) 
                             for k, v in sorted(kwargs.items())))
    print('e.g. dict(**kwargs) (same as {kweg}) returns: \n{0}'.format(
      dict(**kwargs), kweg=kweg))

Wir können in der Online-Hilfe nach der Signatur der Funktion suchen help(foo), was uns sagt

foo(a, b=10, *args, **kwargs)

Rufen wir diese Funktion mit auf foo(1, 2, 3, 4, e=5, f=6, g=7)

welches druckt:

a is a required argument, and its value is 1
b not required, its default value is 10, actual value: 2
args is of type <type 'tuple'> and length 2
unknown arg: 3
unknown arg: 4
kwargs is of type <type 'dict'> and length 3
unknown kwarg - kw: e, arg: 5
unknown kwarg - kw: g, arg: 7
unknown kwarg - kw: f, arg: 6
Args or kwargs can be passed without knowing what they are.
e.g. max(a, b, *args) 
4
e.g. dict(**kwargs) (same as dict(e=5, f=6, g=7)) returns: 
{'e': 5, 'g': 7, 'f': 6}

Beispiel 2

Wir können es auch mit einer anderen Funktion aufrufen, die wir gerade bereitstellen a:

def bar(a):
    b, c, d, e, f = 2, 3, 4, 5, 6
    # dumping every local variable into foo as a keyword argument 
    # by expanding the locals dict:
    foo(**locals()) 

bar(100) druckt:

a is a required argument, and its value is 100
b not required, its default value is 10, actual value: 2
args is of type <type 'tuple'> and length 0
kwargs is of type <type 'dict'> and length 4
unknown kwarg - kw: c, arg: 3
unknown kwarg - kw: e, arg: 5
unknown kwarg - kw: d, arg: 4
unknown kwarg - kw: f, arg: 6
Args or kwargs can be passed without knowing what they are.
e.g. max(a, b, *args) 
100
e.g. dict(**kwargs) (same as dict(c=3, d=4, e=5, f=6)) returns: 
{'c': 3, 'e': 5, 'd': 4, 'f': 6}

Beispiel 3:Praktische Anwendung bei Dekorateuren

Okay, vielleicht sehen wir das Dienstprogramm noch nicht.Stellen Sie sich also vor, Sie hätten mehrere Funktionen mit redundantem Code vor und/oder nach dem differenzierenden Code.Bei den folgenden benannten Funktionen handelt es sich lediglich um Pseudocode zur Veranschaulichung.

def foo(a, b, c, d=0, e=100):
    # imagine this is much more code than a simple function call
    preprocess() 
    differentiating_process_foo(a,b,c,d,e)
    # imagine this is much more code than a simple function call
    postprocess()

def bar(a, b, c=None, d=0, e=100, f=None):
    preprocess()
    differentiating_process_bar(a,b,c,d,e,f)
    postprocess()

def baz(a, b, c, d, e, f):
    ... and so on

Wir können das vielleicht anders handhaben, aber wir können die Redundanz sicherlich mit einem Dekorator extrahieren, und unser Beispiel unten zeigt, wie das geht *args Und **kwargs kann sehr nützlich sein:

def decorator(function):
    '''function to wrap other functions with a pre- and postprocess'''
    @functools.wraps(function) # applies module, name, and docstring to wrapper
    def wrapper(*args, **kwargs):
        # again, imagine this is complicated, but we only write it once!
        preprocess()
        function(*args, **kwargs)
        postprocess()
    return wrapper

Und jetzt kann jede umschlossene Funktion viel prägnanter geschrieben werden, da wir die Redundanz herausgerechnet haben:

@decorator
def foo(a, b, c, d=0, e=100):
    differentiating_process_foo(a,b,c,d,e)

@decorator
def bar(a, b, c=None, d=0, e=100, f=None):
    differentiating_process_bar(a,b,c,d,e,f)

@decorator
def baz(a, b, c=None, d=0, e=100, f=None, g=None):
    differentiating_process_baz(a,b,c,d,e,f, g)

@decorator
def quux(a, b, c=None, d=0, e=100, f=None, g=None, h=None):
    differentiating_process_quux(a,b,c,d,e,f,g,h)

Und indem wir unseren Code herausrechnen, der *args Und **kwargs Dadurch reduzieren wir die Anzahl der Codezeilen, verbessern die Lesbarkeit und Wartbarkeit und verfügen über alleinige kanonische Speicherorte für die Logik in unserem Programm.Wenn wir einen Teil dieser Struktur ändern müssen, haben wir einen Ort, an dem wir jede Änderung vornehmen können.

Lassen Sie uns zunächst verstehen, was Positionsargumente und Schlüsselwortargumente sind.Unten finden Sie ein Beispiel für eine Funktionsdefinition mit Positionsargumente.

def test(a,b,c):
     print(a)
     print(b)
     print(c)

test(1,2,3)
#output:
1
2
3

Dies ist also eine Funktionsdefinition mit Positionsargumenten.Sie können es auch mit Schlüsselwörtern/benannten Argumenten aufrufen:

def test(a,b,c):
     print(a)
     print(b)
     print(c)

test(a=1,b=2,c=3)
#output:
1
2
3

Lassen Sie uns nun ein Beispiel für die Funktionsdefinition mit untersuchen Schlüsselwortargumente:

def test(a=0,b=0,c=0):
     print(a)
     print(b)
     print(c)
     print('-------------------------')

test(a=1,b=2,c=3)
#output :
1
2
3
-------------------------

Sie können diese Funktion auch mit Positionsargumenten aufrufen:

def test(a=0,b=0,c=0):
    print(a)
    print(b)
    print(c)
    print('-------------------------')

test(1,2,3)
# output :
1
2
3
---------------------------------

Damit kennen wir nun Funktionsdefinitionen mit Positionsargumenten und Schlüsselwortargumenten.

Lassen Sie uns nun den Operator „*“ und den Operator „**“ untersuchen.

Bitte beachten Sie, dass diese Operatoren in zwei Bereichen verwendet werden können:

A) Funktionsaufruf

B) Funktionsdefinition

Die Verwendung der Operatoren „*“ und „**“ in Funktionsaufruf.

Kommen wir gleich zu einem Beispiel und diskutieren es dann.

def sum(a,b):  #receive args from function calls as sum(1,2) or sum(a=1,b=2)
    print(a+b)

my_tuple = (1,2)
my_list = [1,2]
my_dict = {'a':1,'b':2}

# Let us unpack data structure of list or tuple or dict into arguments with help of '*' operator
sum(*my_tuple)   # becomes same as sum(1,2) after unpacking my_tuple with '*'
sum(*my_list)    # becomes same as sum(1,2) after unpacking my_list with  '*'
sum(**my_dict)   # becomes same as sum(a=1,b=2) after unpacking by '**' 

# output is 3 in all three calls to sum function.

Also denk daran

wenn der Operator „*“ oder „**“ in a verwendet wird Funktionsaufruf -

Der Operator „*“ entpackt Datenstrukturen wie eine Liste oder ein Tupel in Argumente, die für die Funktionsdefinition benötigt werden.

Der Operator „**“ entpackt ein Wörterbuch in Argumente, die für die Funktionsdefinition erforderlich sind.

Lassen Sie uns nun die Verwendung des „*“-Operators in untersuchen Funktionsdefinition.Beispiel:

def sum(*args): #pack the received positional args into data structure of tuple. after applying '*' - def sum((1,2,3,4))
    sum = 0
    for a in args:
        sum+=a
    print(sum)

sum(1,2,3,4)  #positional args sent to function sum
#output:
10

In Funktion Definition Der Operator „*“ packt die empfangenen Argumente in ein Tupel.

Sehen wir uns nun ein Beispiel für die Verwendung von „**“ in der Funktionsdefinition an:

def sum(**args): #pack keyword args into datastructure of dict after applying '**' - def sum({a:1,b:2,c:3,d:4})
    sum=0
    for k,v in args.items():
        sum+=v
    print(sum)

sum(a=1,b=2,c=3,d=4) #positional args sent to function sum

In Funktion Definition Der Operator „**“ packt die empfangenen Argumente in ein Wörterbuch.

Also denk daran:

In einem Funktionsaufruf Die '*' packt aus Datenstruktur eines Tupels oder einer Liste in Positions- oder Schlüsselwortargumente, die von der Funktionsdefinition empfangen werden sollen.

In einem Funktionsaufruf Die '**' packt aus Datenstruktur des Wörterbuchs in Positions- oder Schlüsselwortargumente, die von der Funktionsdefinition empfangen werden sollen.

In einem Funktionsdefinition Die '*' Packungen Positionsargumente in ein Tupel.

In einem Funktionsdefinition Die '**' Packungen Schlüsselwortargumente in ein Wörterbuch.

* Und ** haben eine besondere Verwendung in der Liste der Funktionsargumente. *impliziert, dass das Argument eine Liste ist und ** impliziert, dass das Argument ein Wörterbuch ist.Auf diese Weise können Funktionen willkürliche Anzahl von Argumenten aufnehmen

Es gab zwar Verwendungsmöglichkeiten für die Star/Splat-Operatoren erweitert In Python 3 gefällt mir die folgende Tabelle, da sie sich auf die Verwendung dieser Operatoren bezieht mit Funktionen.Der/die Splat-Operator(en) können in beiden Funktionen verwendet werden Konstruktion und in der Funktion Anruf:

            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 dient eigentlich nur dazu, Lorin Hochsteins Werk zusammenzufassen Antwort aber ich finde es hilfreich.

Für diejenigen unter Ihnen, die durch Beispiele lernen!

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

Lassen Sie uns dies zeigen, indem wir eine Funktion definieren, die zwei normale Variablen akzeptiert x, y, und kann mehr Argumente akzeptieren als myArgs, und kann noch mehr Argumente akzeptieren als myKW.Später zeigen wir, wie man füttert y verwenden 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 Wörterbüchern vorbehalten.
  2. Zuerst erfolgt die nicht optionale Argumentzuweisung.
  3. Sie können ein nicht optionales Argument nicht zweimal verwenden.
  4. Wenn anwendbar, ** muss danach kommen *, stets.

Aus der Python-Dokumentation:

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

Wenn ein Schlüsselwortargument keinem formalen Parameternamen entspricht, wird eine TypeError-Ausnahme ausgelöst, es sei denn, ein formaler Parameter mit der Syntax „**identifier“ ist vorhanden;In diesem Fall erhält dieser formale Parameter ein Wörterbuch, das die überschüssigen Schlüsselwortargumente enthält (wobei die Schlüsselwörter als Schlüssel und die Argumentwerte als entsprechende Werte verwendet werden), oder ein (neues) leeres Wörterbuch, wenn es keine überschüssigen Schlüsselwortargumente gab.

In Python 3.5 können Sie diese Syntax auch verwenden list, dict, tuple, Und set Displays (manchmal auch Literale genannt).Sehen PEP 488:Zusätzliche Verallgemeinerungen zum Auspacken.

>>> (0, *range(1, 4), 5, *range(6, 8))
(0, 1, 2, 3, 5, 6, 7)
>>> [0, *range(1, 4), 5, *range(6, 8)]
[0, 1, 2, 3, 5, 6, 7]
>>> {0, *range(1, 4), 5, *range(6, 8)}
{0, 1, 2, 3, 5, 6, 7}
>>> d = {'one': 1, 'two': 2, 'three': 3}
>>> e = {'six': 6, 'seven': 7}
>>> {'zero': 0, **d, 'five': 5, **e}
{'five': 5, 'seven': 7, 'two': 2, 'one': 1, 'three': 3, 'six': 6, 'zero': 0}

Außerdem können mehrere Iterables in einem einzigen Funktionsaufruf entpackt werden.

>>> range(*[1, 10], *[2])
range(1, 10, 2)

(Danke an mgilson für den PEP-Link.)

Ich möchte ein Beispiel nennen, das andere nicht erwähnt haben

* kann auch a auspacken Generator

Ein Beispiel aus dem Python3-Dokument

x = [1, 2, 3]
y = [4, 5, 6]

unzip_x, unzip_y = zip(*zip(x, y))

unzip_x wird [1, 2, 3] sein, unzip_y wird [4, 5, 6] sein

Das zip() empfängt mehrere iretable-Argumente und gibt einen Generator zurück.

zip(*zip(x,y)) -> zip((1, 4), (2, 5), (3, 6))

Zusätzlich zu Funktionsaufrufen sind *args und **kwargs in Klassenhierarchien nützlich und ersparen auch das Schreiben __init__ Methode in Python.Eine ähnliche Verwendung kann in Frameworks wie Django-Code beobachtet werden.

Zum Beispiel,

def __init__(self, *args, **kwargs):
    for attribute_name, value in zip(self._expected_attributes, args):
        setattr(self, attribute_name, value)
        if kwargs.has_key(attribute_name):
            kwargs.pop(attribute_name)

    for attribute_name in kwargs.viewkeys():
        setattr(self, attribute_name, kwargs[attribute_name])

Eine Unterklasse kann dann sein

class RetailItem(Item):
    _expected_attributes = Item._expected_attributes + ['name', 'price', 'category', 'country_of_origin']

class FoodItem(RetailItem):
    _expected_attributes = RetailItem._expected_attributes +  ['expiry_date']

Die Unterklasse wird dann instanziiert als

food_item = FoodItem(name = 'Jam', 
                     price = 12.0, 
                     category = 'Foods', 
                     country_of_origin = 'US', 
                     expiry_date = datetime.datetime.now())

Außerdem kann eine Unterklasse mit einem neuen Attribut, das nur für diese Unterklasseninstanz sinnvoll ist, die Basisklasse aufrufen __init__ um die Attributeinstellung auszulagern.Dies geschieht über *args und **kwargs.kwargs werden hauptsächlich verwendet, damit Code mithilfe benannter Argumente lesbar ist.Zum Beispiel,

class ElectronicAccessories(RetailItem):
    _expected_attributes = RetailItem._expected_attributes +  ['specifications']
    # Depend on args and kwargs to populate the data as needed.
    def __init__(self, specifications = None, *args, **kwargs):
        self.specifications = specifications  # Rest of attributes will make sense to parent class.
        super(ElectronicAccessories, self).__init__(*args, **kwargs)

was instatiiert werden kann als

usb_key = ElectronicAccessories(name = 'Sandisk', 
                                price = '$6.00', 
                                category = 'Electronics',
                                country_of_origin = 'CN',
                                specifications = '4GB USB 2.0/USB 3.0')

Der vollständige Code ist Hier

* bedeutet, variable Argumente als Liste zu empfangen

** bedeutet, variable Argumente als Wörterbuch zu empfangen

Wird wie folgt verwendet:

1) Single *

def foo(*args):
    for arg in args:
        print(arg)

foo("two", 3)

Ausgabe:

two
3

2) Jetzt **

def bar(**kwargs):
    for key in kwargs:
        print(key, kwargs[key])

bar(dic1="two", dic2=3)

Ausgabe:

dic1 two
dic2 3

Ein gutes Beispiel für die Verwendung von beidem in einer Funktion ist:

>>> def foo(*arg,**kwargs):
...     print arg
...     print kwargs
>>>
>>> a = (1, 2, 3)
>>> b = {'aa': 11, 'bb': 22}
>>>
>>>
>>> foo(*a,**b)
(1, 2, 3)
{'aa': 11, 'bb': 22}
>>>
>>>
>>> foo(a,**b) 
((1, 2, 3),)
{'aa': 11, 'bb': 22}
>>>
>>>
>>> foo(a,b) 
((1, 2, 3), {'aa': 11, 'bb': 22})
{}
>>>
>>>
>>> foo(a,*b)
((1, 2, 3), 'aa', 'bb')
{}

Dieses Beispiel soll Ihnen beim Erinnern helfen *args, **kwargs und selbst super und Vererbung in Python gleichzeitig.

class base(object):
    def __init__(self, base_param):
        self.base_param = base_param


class child1(base): # inherited from base class
    def __init__(self, child_param, *args) # *args for non-keyword args
        self.child_param = child_param
        super(child1, self).__init__(*args) # call __init__ of the base class and initialize it with a NON-KEYWORD arg

class child2(base):
    def __init__(self, child_param, **kwargs):
        self.child_param = child_param
        super(child2, self).__init__(**kwargs) # call __init__ of the base class and initialize it with a KEYWORD arg

c1 = child1(1,0)
c2 = child2(1,base_param=0)
print c1.base_param # 0
print c1.child_param # 1
print c2.base_param # 0
print c2.child_param # 1

TL;DR

Es packt an die Funktion übergebene Argumente in list Und dict jeweils innerhalb des Funktionskörpers.Wenn Sie eine Funktionssignatur wie folgt definieren:

def func(*args, **kwds):
    # do stuff

Es kann mit einer beliebigen Anzahl von Argumenten und Schlüsselwortargumenten aufgerufen werden.Die Nicht-Schlüsselwortargumente werden in eine Liste mit dem Namen gepackt args Innerhalb werden der Funktionskörper und die Schlüsselwortargumente in ein aufgerufenes Diktat gepackt kwds innerhalb des Funktionskörpers.

func("this", "is a list of", "non-keyowrd", "arguments", keyword="ligma", options=[1,2,3])

Jetzt gibt es im Funktionskörper beim Aufruf der Funktion zwei lokale Variablen: args Das ist eine Liste mit Wert ["this", "is a list of", "non-keyword", "arguments"] Und kwds die ein dict Wert haben {"keyword" : "ligma", "options" : [1,2,3]}


Dies funktioniert auch umgekehrt, d.h.von der Anruferseite.Wenn Sie beispielsweise eine Funktion definiert haben als:

def f(a, b, c, d=1, e=10):
    # do stuff

Sie können es aufrufen, indem Sie Iterables oder Mappings entpacken, die Sie im aufrufenden Bereich haben:

iterable = [1, 20, 500]
mapping = {"d" : 100, "e": 3}
f(*iterable, **mapping)
# That call is equivalent to
f(1, 20, 500, d=100, e=3)

*args Und **kwargs:ermöglichen es Ihnen, einer Funktion eine variable Anzahl von Argumenten zu übergeben.

*args:wird verwendet, um eine Argumentliste variabler Länge ohne Schlüsselwort an die Funktion zu senden:

def args(normal_arg, *argv):
    print("normal argument:", normal_arg)

    for arg in argv:
        print("Argument in list of arguments from *argv:", arg)

args('animals', 'fish', 'duck', 'bird')

Wird herstellen:

normal argument: animals
Argument in list of arguments from *argv: fish
Argument in list of arguments from *argv: duck
Argument in list of arguments from *argv: bird

**kwargs*

**kwargs ermöglicht es Ihnen, mit Schlüsselwörtern versehene Argumente variabler Länge an eine Funktion zu übergeben.Du solltest benutzen **kwargs wenn Sie benannte Argumente in einer Funktion verarbeiten möchten.

def who(**kwargs):
    if kwargs is not None:
        for key, value in kwargs.items():
            print("Your %s is %s." % (key, value))

who(name="Nikola", last_name="Tesla", birthday="7.10.1856", birthplace="Croatia")  

Wird herstellen:

Your name is Nikola.
Your last_name is Tesla.
Your birthday is 7.10.1856.
Your birthplace is Croatia.
  • def foo(param1, *param2): ist eine Methode, für die eine beliebige Anzahl von Werten akzeptiert werden kann *param2,
  • def bar(param1, **param2): ist eine Methode, die eine beliebige Anzahl von Werten mit Schlüsseln für akzeptieren kann *param2
  • param1 ist ein einfacher Parameter.

Zum Beispiel die Syntax für die Implementierung Varargs in Java wie folgt:

accessModifier methodName(datatype… arg) {
    // method body
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top