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.

8voto

quiet_penguin Punkte 758

Zusätzlich zu den Funktionsaufrufen sind *args und **kwargs in Klassenhierarchien nützlich und vermeiden auch, dass man schreiben muss __init__ Methode in Python. Eine ähnliche Verwendung kann in Frameworks wie Django-Code gesehen 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

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 Einstellung der Attribute auszulagern. Dies geschieht durch *args und **kwargs. kwargs wird hauptsächlich verwendet, damit der Code mit benannten Argumenten 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)

die wie folgt eingesetzt werden kann

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 lautet aquí

5voto

etoricky Punkte 541

Gegeben eine Funktion, die 3 Elemente als Argument hat

sum = lambda x, y, z: x + y + z
sum(1,2,3) # sum 3 items

sum([1,2,3]) # error, needs 3 items, not 1 list

x = [1,2,3][0]
y = [1,2,3][1]
z = [1,2,3][2]
sum(x,y,z) # ok

sum(*[1,2,3]) # ok, 1 list becomes 3 items

Stellen Sie sich dieses Spielzeug mit einem Beutel mit einem dreieckigen, einem kreisförmigen und einem rechteckigen Gegenstand vor. Diese Tüte passt nicht direkt hinein. Man muss die Tüte auspacken, um diese 3 Gegenstände zu nehmen, und schon passen sie. Der Python-Operator * führt diesen Auspackvorgang durch.

enter image description here

4voto

Hrvoje Punkte 9859

*args y **kwargs : Erlaubt die Übergabe einer variablen Anzahl von Argumenten an eine Funktion.

*args : wird verwendet, um eine Argumentliste mit 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 produzieren:

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, Argumente mit variabler Länge an eine Funktion zu übergeben. Sie sollten verwenden **kwargs wenn Sie benannte Argumente in einer Funktion behandeln wollen.

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 produzieren:

Your name is Nikola.
Your last_name is Tesla.
Your birthday is 7.10.1856.
Your birthplace is Croatia.

3voto

thanhtang Punkte 826

Dieses Beispiel soll Ihnen helfen, sich zu erinnern *args , **kwargs und sogar super und Vererbung in Python auf einmal.

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

3voto

amir jj Punkte 214

Ein gutes Beispiel für die Verwendung beider 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')
{}

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