Que font ** (double étoile/astérisque) et * (étoile/astérisque) pour les paramètres?
dans les définitions de méthode suivantes, Que font les *
et **
pour param2
?
def foo(param1, *param2):
def bar(param1, **param2):
18 réponses
le *args
et **kwargs
est un langage courant pour permettre un nombre arbitraire d'arguments aux fonctions comme décrit dans la section plus sur la définition des fonctions dans la documentation Python.
le *args
vous donnera tous les paramètres de fonction comme un tuple :
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
le **kwargs
vous donnera tout
mots-clés arguments sauf pour ceux correspondant à un paramètre formel comme un dictionnaire.
In [5]: def bar(**kwargs):
...: for a in kwargs:
...: print a, kwargs[a]
...:
...:
In [6]: bar(name='one', age=27)
age 27
name one
les deux idiomes peuvent être mélangés avec des arguments normaux pour permettre un ensemble d'arguments fixes et quelques variables:
def foo(kind, *args, **kwargs):
pass
un autre usage de l'idiome *l
est de despack argument lists lors de l'appel d'une fonction.
In [9]: def foo(bar, lee):
...: print bar, lee
...:
...:
In [10]: l = [1,2]
In [11]: foo(*l)
1 2
En Python 3, il est possible d'utiliser *l
sur le côté gauche d'une affectation ( déballage itératif étendu ), bien qu'il donne une liste au lieu d'un tuple dans ce contexte:
first, *rest = [1,2,3,4]
first, *l, last = [1,2,3,4]
aussi Python 3 ajoute nouvelle sémantique (se référer PEP 3102 ):
def func(arg1, arg2, arg3, *, kwarg1, kwarg2):
pass
une telle fonction n'accepte que 3 arguments de position, et tout ce qui suit *
ne peut être passé qu'en tant qu'arguments de mots clés.
Il est également intéressant de noter que vous pouvez utiliser *
et **
lors de l'appel de fonctions. C'est un raccourci qui vous permet de passer plusieurs arguments à une fonction directement en utilisant une liste/tuple ou un dictionnaire. Par exemple, si vous avez la fonction suivante:
def foo(x,y,z):
print("x=" + str(x))
print("y=" + str(y))
print("z=" + str(z))
vous pouvez faire des choses comme:
>>> 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
Remarque: Les touches mydict
être nommé exactement comme les paramètres de la fonction foo
. Sinon il lancera un 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'
le simple * signifie qu'il peut y avoir n'importe quel nombre d'arguments de position supplémentaires. foo()
peut être invoqué comme foo(1,2,3,4,5)
. Dans le corps de foo () param2 est une séquence contenant 2-5.
le double ** signifie qu'il peut y avoir n'importe quel nombre de paramètres nommés supplémentaires. bar()
peut être invoqué comme bar(1, a=2, b=3)
. Dans le corps de bar() param2 est un dictionnaire contenant {'a':2, 'b':3 }
avec le code suivant:
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)
la sortie est
1
(2, 3, 4, 5)
1
{'a': 2, 'b': 3}
Quoi
**
(étoile double) et*
(l'étoile) à faire pour les paramètres
ils permettent aux fonctions d'être défini pour accepter et pour utilisateurs de passer n'importe quel nombre d'arguments, de position ( *
) et de mot-clé ( **
).
Définition Des Fonctions
*args
permet un nombre quelconque d'options arguments de position (paramètres), qui seront assignés à un tuple nommé args
.
**kwargs
permet pour n'importe quel nombre d'arguments (paramètres) de mot-clé optionnel, qui sera dans un dict nommé kwargs
.
vous pouvez (et devriez) choisir n'importe quel nom approprié, mais si l'intention est que les arguments soient de sémantique non-spécifique, args
et kwargs
sont des noms standard.
Expansion, Passer un certain nombre d'arguments
vous pouvez également utiliser *args
et **kwargs
pour passer dans les paramètres des listes (ou n'importe quel itérable) et dicts (ou n'importe quel mapping), respectivement.
la fonction recevant les paramètres n'a pas besoin de savoir qu'ils sont élargis.
par exemple, xrange de Python 2 n'attend pas explicitement *args
, mais puisqu'il prend 3 entiers comme arguments:
>>> x = xrange(3) # create our *args - an iterable of 3 integers
>>> xrange(*x) # expand here
xrange(0, 2, 2)
comme autre exemple, nous pouvons utiliser l'expansion de dict dans str.format
:
>>> foo = 'FOO'
>>> bar = 'BAR'
>>> 'this is foo, {foo} and bar, {bar}'.format(**locals())
'this is foo, FOO and bar, BAR'
nouveau en Python 3: définition de fonctions avec des arguments mot-clé seulement
vous pouvez avoir arguments mot-clé seulement après le *args
- par exemple, ici, kwarg2
doit être donné comme un argument mot-clé - pas positionnellement:
def foo(arg, kwarg=None, *args, kwarg2=None, **kwargs):
return arg, kwarg, args, kwarg2, kwargs
Utilisation:
>>> foo(1,2,3,4,5,kwarg2='kwarg2', bar='bar', baz='baz')
(1, 2, (3, 4, 5), 'kwarg2', {'bar': 'bar', 'baz': 'baz'})
aussi, *
peut être utilisé par lui-même pour indiquer que le mot-clé seulement les arguments suivent, sans permettre des arguments de position illimités.
def foo(arg, kwarg=None, *, kwarg2=None, **kwargs):
return arg, kwarg, kwarg2, kwargs
ici, kwarg2
encore une fois doit être un argument de mot-clé explicitement nommé:
>>> foo(1,2,kwarg2='kwarg2', foo='foo', bar='bar')
(1, 2, 'kwarg2', {'foo': 'foo', 'bar': 'bar'})
et nous ne pouvons plus accepter les arguments de position illimités parce que nous n'avons pas *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
encore une fois, plus simplement, nous avons besoin kwarg
à donner par nom, et non positionnellement:
def bar(*, kwarg=None):
return kwarg
dans cet exemple, nous voyons que si nous essayons de passer kwarg
positionnellement, nous obtenons une erreur:
>>> bar('kwarg')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: bar() takes 0 positional arguments but 1 was given
nous devons explicitement passer le paramètre kwarg
comme un argument de mot-clé.
>>> bar(kwarg='kwarg')
'kwarg'
Python 2 compatible demos
*args
(typiquement dit" star-args") et **kwargs
(les étoiles peuvent être impliquées par dire "kwargs", mais être explicite avec" double étoile kwargs") sont des idiomes courants de Python pour utiliser la notation *
et **
. Ces noms de variables spécifiques ne sont pas nécessaires (par exemple, vous pouvez utiliser *foos
et **bars
), mais une dérogation à la convention est susceptible d'enrager vos codeurs Python.
généralement, Nous utilisons lorsque nous ne savons pas ce que notre fonction va recevoir ou combien d'arguments on peut passer, et parfois même en nommant chaque variable séparément serait très confus et redondant (mais c'est un cas où généralement explicite est mieux qu'implicite).
exemple 1
la fonction suivante décrit comment ils peuvent être utilisés, et démontre le comportement. Remarque le nom b
argument sera consommée par la deuxième position argument avant :
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))
nous pouvons vérifier l'aide en ligne pour la signature de la fonction, avec help(foo)
, qui nous dit
foo(a, b=10, *args, **kwargs)
appelons cette fonction avec foo(1, 2, 3, 4, e=5, f=6, g=7)
qui imprime:
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}
exemple 2
nous pouvons également l'appeler en utilisant une autre fonction, dans laquelle nous venons de fournir 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)
gravures:
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}
exemple 3: usage pratique dans les décorateurs
OK, donc peut-être que nous ne voyons pas encore l'utilité. Alors imaginez que vous ayez plusieurs fonctions avec du code redondant avant et/ou après le code de différenciation. Les fonctions nommées ci-dessous ne sont que du pseudo-code à titre indicatif.
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
nous pourrions être en mesure de gérer cela différemment, mais nous pouvons certainement extraire la redondance avec un décorateur, et donc notre exemple ci-dessous montre comment *args
et **kwargs
peuvent être très utiles:
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
et maintenant chaque fonction enveloppée peut être écrite beaucoup plus succinctement, comme nous avons supprimé la redondance:
@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)
et en factorisant notre code, que *args
et **kwargs
nous permet de faire, nous réduisons les lignes de code, améliorer la lisibilité et la maintenabilité, et ont des emplacements canoniques uniques pour la logique dans notre programme. Si nous avons besoin de modifier une partie de cette structure, nous avons une place pour chaque changement.
commençons par comprendre ce que sont les arguments de position et les arguments de mots clés. Voici un exemple de définition de fonction avec des arguments de position .
def test(a,b,c):
print(a)
print(b)
print(c)
test(1,2,3)
#output:
1
2
3
il s'agit donc d'une définition de fonction avec des arguments de position. Vous pouvez l'appeler avec des mots-clés/arguments nommés aussi bien:
def test(a,b,c):
print(a)
print(b)
print(c)
test(a=1,b=2,c=3)
#output:
1
2
3
maintenant, étudions un exemple de définition de fonction avec mots clés arguments :
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
-------------------------
vous pouvez aussi appeler cette fonction avec des arguments de position:
def test(a=0,b=0,c=0):
print(a)
print(b)
print(c)
print('-------------------------')
test(1,2,3)
# output :
1
2
3
---------------------------------
ainsi nous connaissons maintenant des définitions de fonction avec des arguments de position aussi bien que des mots-clés.
étudions maintenant l'opérateur ' * 'et'**'.
veuillez noter que ces opérateurs peuvent être utilisés dans 2 zones:
a) appel de fonction
b) définition de la fonction
L'utilisation de '*' et '**' opérateur appel de fonction.
allons droit à un exemple et discutons-en.
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.
, Donc n'oubliez pas
lorsque l'opérateur " * " ou "* * "est utilisé dans un appel de fonction 151990920" -
'*' opérateur déballe structure de données telle qu'une liste ou tuple dans les arguments nécessaires par la définition de la fonction.
'**' opérateur décompresse un dictionnaire dans les arguments requis par la définition de la fonction.
étudions maintenant l'utilisation de l'opérateur " * "dans définition de la fonction . Exemple:
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
Dans la fonction définition ' * ' opérateur de paquets reçus des arguments dans un tuple.
voyons maintenant un exemple de '**' utilisé dans la définition de la fonction:
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
Dans la fonction définition Les '**' opérateur de paquets reçus des arguments dans un dictionnaire.
Donc n'oubliez pas:
Dans un appel de fonction ' * ' déballe la structure de données de tuple ou une liste en position ou un mot-clé arguments à être reçu par la définition de la fonction.
dans un appel de fonction les '**' déballe la structure de données de dictionnaire en position ou un mot-clé arguments à être reçu par la définition de la fonction.
Dans un définition de la fonction ' * ' packs les arguments de position dans un tuple.
Dans un définition de la fonction les '**' packs mot-clé arguments dans un dictionnaire.
*
et **
ont une utilisation particulière de la fonction de la liste d'arguments. *
implique que l'argument est une liste et **
implique que l'argument
est un dictionnaire. Cela permet fonctions pour prendre nombre arbitraire de
arguments
de la documentation Python:
S'il y a plus d'arguments de position qu'il n'y a de slots de paramètres formels, une exception TypeError est soulevée, à moins qu'un paramètre formel utilisant la syntaxe" *identifier " ne soit présent; dans ce cas, ce paramètre formel reçoit un tuple contenant les arguments de position en excès (ou un tuple vide s'il n'y avait pas d'arguments de position en excès).
si un argument de mot-clé ne correspond à un nom de paramètre formel, une exception TypeError est soulevée, sauf si un paramètre formel utilisant la syntaxe "**identifier" est présent; dans ce cas, ce paramètre formel reçoit un dictionnaire contenant les arguments de mot-clé en excès (en utilisant les mots-clés comme clés et les valeurs d'argument comme valeurs correspondantes), ou un (nouveau) dictionnaire vide s'il n'y avait pas d'arguments de mot-clé en excès.
alors que les utilisations pour les opérateurs star/splat ont été expanded en Python 3, j'aime le tableau suivant en ce qui concerne l'utilisation de ces opérateurs avec des fonctions . Le ou les opérateurs splat peuvent être utilisés à la fois dans la fonction construction et dans la fonction appel :
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) |
-----------------------------------------------------------------------
- Ce vraiment juste sert à résumer Lorin Hochstein réponse mais je trouve utile.
je veux donner un exemple que d'autres n'ont pas mentionné
* peut aussi déballer une génératrice
un exemple du Document Python3
x = [1, 2, 3]
y = [4, 5, 6]
unzip_x, unzip_y = zip(*zip(x, y))
unzip_x sera [1, 2, 3], unzip_y sera [4, 5, 6]
le zip() reçoit plusieurs args iretables, et renvoie un générateur.
zip(*zip(x,y)) -> zip((1, 4), (2, 5), (3, 6))
en Python 3.5, vous pouvez également utiliser cette syntaxe list
, dict
, tuple
, et set
affiche (parfois appelé aussi littérales). Voir PEP 488: Généralités supplémentaires sur le déballage .
>>> (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}
permet également de déballer plusieurs itérables dans un appel de fonction unique.
>>> range(*[1, 10], *[2])
range(1, 10, 2)
(merci à mgilson pour le lien PEP.)
Pour ceux d'entre vous qui apprennent par exemples!
- le but de
*
est de vous donner la capacité de définir une fonction qui peut prendre un nombre arbitraire d'arguments fournis comme une liste (par exemplef(*myList)
). - le but de
**
est de vous donner la capacité d'alimenter les arguments d'une fonction en fournissant un dictionnaire (par exemplef(**{'x' : 1, 'y' : 2})
).
montrons ceci par définir une fonction qui prend deux variables normales x
, y
, et peut accepter plus d'arguments que myArgs
, et peut accepter encore plus d'arguments que myKW
. Plus tard, nous montrerons comment alimenter y
en utilisant 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 = {}
# ----------------------------------------------------------------------
mises en garde
-
**
est exclusivement réservé aux dictionnaires. - Non-argument optionnel affectation a lieu en premier.
- vous ne pouvez pas utiliser un argument non-optionnel deux fois.
- si applicable,
**
doit venir après*
, toujours.
en plus des appels de fonction, *args et **kwargs sont utiles dans les hiérarchies de classe et évitent également d'avoir à écrire la méthode __init__
en Python. Un usage similaire peut être vu dans des cadres comme le code Django.
par exemple,
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])
une sous-classe peut alors être
class RetailItem(Item):
_expected_attributes = Item._expected_attributes + ['name', 'price', 'category', 'country_of_origin']
class FoodItem(RetailItem):
_expected_attributes = RetailItem._expected_attributes + ['expiry_date']
la sous-classe doit alors être instanciée comme
food_item = FoodItem(name = 'Jam',
price = 12.0,
category = 'Foods',
country_of_origin = 'US',
expiry_date = datetime.datetime.now())
Aussi, une sous-classe avec un nouvel attribut qui fait sens seule cette instance de la sous-classe peut appeler la classe de Base __init__
pour désactiver le paramètre attributs.
Cela se fait par *args et **kwargs. kwargs utilisé principalement pour que le code soit lisible en utilisant les arguments nommés. Par exemple,
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)
qui peut être mis en place comme
usb_key = ElectronicAccessories(name = 'Sandisk',
price = '.00',
category = 'Electronics',
country_of_origin = 'CN',
specifications = '4GB USB 2.0/USB 3.0')
le code complet est ici
un bon exemple d'utilisation des deux dans une fonction est:
>>> 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')
{}
cet exemple vous aiderait à vous souvenir de *args
, **kwargs
et même super
et de l'héritage en Python à la fois.
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
*args
et **kwargs
: vous permettent de passer un nombre variable d'arguments à une fonction.
*args
: est utilisé pour envoyer une liste d'arguments de longueur de variable non-keyworded à la fonction:
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')
produira:
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
vous permet de passer la longueur variable des arguments à une fonction. Vous devez utiliser **kwargs
si vous souhaitez gérer des arguments nommés dans une fonction.
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")
produira:
Your name is Nikola.
Your last_name is Tesla.
Your birthday is 7.10.1856.
Your birthplace is Croatia.
*
signifie recevoir variable d'arguments de la liste
**
signifie recevoir variable d'arguments que dictionnaire
utilisé comme suit:
1) simple *
def foo(*args):
for arg in args:
print(arg)
foo("two", 3)
sortie:
two
3
2) Maintenant **
def bar(**kwargs):
for key in kwargs:
print(key, kwargs[key])
bar(dic1="two", dic2=3)
sortie:
dic1 two
dic2 3
-
def foo(param1, *param2):
est une méthode qui peut accepter un nombre arbitraire de valeurs pour*param2
, -
def bar(param1, **param2):
est une méthode qui peut accepter un nombre arbitraire de valeurs avec des clés pour*param2
-
param1
est un paramètre simple.
par exemple, la syntaxe pour mettre en œuvre varargs en Java comme suit:
accessModifier methodName(datatype… arg) {
// method body
}
* args = *aList = tous les éléments d'une liste
**args= ** aDict =tous les éléments dans un dict