Was tun *args
y **kwargs
bedeuten?
def foo(x, y, *args):
def bar(x, y, **kwargs):
Was tun *args
y **kwargs
bedeuten?
def foo(x, y, *args):
def bar(x, y, **kwargs):
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í
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.
*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.
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
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 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.
14 Stimmen
Siehe auch stackoverflow.com/questions/6967632/
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.1 Stimmen
Diese Frage ist - wie viele sehr alte Fragen - irgendwie verkehrt. Normalerweise sollte sich eine Frage darauf beziehen, wie man ein Problem in neuem Code löst, und nicht darauf, wie man bestehenden Code versteht. Für letzteres gilt: Wenn Sie etwas anderes als Duplikat schließen, sollten Sie stackoverflow.com/questions/1993727/ (dies gilt allerdings nur für
*
und nicht**
).