Je dois aller avec M. Lott sur celui-ci. Vous pouvez rapidement obtenir une réponse faisant autorité sur celle-ci dans les documents Python, et vous aurez une idée de ce qu'il y a d'autre dans les documents. Il est à votre avantage d'apprendre à connaître ces documents si vous prévoyez de travailler en Python.
Oui. Vous pouvez utiliser *argscomme argument non mot-clé . Vous pourrez alors passer n'importe quel nombre d'arguments.
def manyArgs(*arg):print"I was called with", len(arg),"arguments:", arg
>>> manyArgs(1)
I was called with1 arguments:(1,)>>> manyArgs(1,2,3)
I was called with3 arguments:(1,2,3)
Comme vous pouvez le voir, Python décompresse les arguments en un seul tuple avec tous les arguments.
Pour les arguments de mots clés, vous devez les accepter comme un argument réel distinct, comme indiqué dans la réponse de Skurmedel .
Aussi important ... on peut trouver un moment où ils doivent passer un nombre inconnu d'arguments à une fonction. Dans un cas comme celui-ci, appelez votre "manyArgs" en créant une liste appelée "args" et en la passant à manyArgs comme ceci "manyArgs (* args)"
wilbbe01
4
C'est proche, mais ce n'est malheureusement pas assez général: manyArgs(x = 3)échoue avec TypeError. La réponse de Skumedel montre la solution à cela. Le point clé est que la signature générale d'une fonction est f(*list_args, **keyword_args)(pas f(*list_args)).
Eric O Lebigot
2
Le type de argsest tuple. kwargssignifie args mot-clé . Le type de kwargsest dictionary.
RoboAlex
1
Juste for arg in args:pour l'itération des
arguments
228
Ajout au déroulement de la publication:
Vous pouvez également envoyer plusieurs arguments de valeur-clé.
def myfunc(**kwargs):# kwargs is a dictionary.for k,v in kwargs.iteritems():print"%s = %s"%(k, v)
myfunc(abc=123, efh=456)# abc = 123# efh = 456
Et vous pouvez mélanger les deux:
def myfunc2(*args,**kwargs):for a in args:print a
for k,v in kwargs.iteritems():print"%s = %s"%(k, v)
myfunc2(1,2,3, banan=123)# 1# 2# 3# banan = 123
Ils doivent être à la fois déclarés et appelés dans cet ordre, c'est-à-dire que la signature de fonction doit être * args, ** kwargs et appelée dans cet ordre.
Je ne sais pas comment vous avez réussi à faire fonctionner myfunc (abc = 123, def = 456), mais dans le mien (2.7), 'def' ne peut pas être passé dans cette fonction sans obtenir une SyntaxError. Je suppose que c'est parce que def a un sens en python. Essayez plutôt myfunc (abc = 123, fgh = 567). (Sinon, excellente réponse et merci!)
Dannid
@Dannid: Aucune idée non plus haha ... ne fonctionne pas non plus sur 2.6 ou 3.2. Je vais le renommer.
Skurmedel
Quand vous dites «appelé dans cet ordre», voulez-vous dire passé dans cet ordre? Ou autre chose?
Nikhil Prabhu
1
@NikhilPrabhu: Ouais. Les arguments des mots clés doivent arriver en dernier lorsque vous l'appelez. Ils viennent toujours en dernier si vous avez également des arguments autres que des mots clés.
Skurmedel
2
Pour Python 3: échangez simplement print aavec print(a)et kwargs.iteritems():avec kwargs.items().
MasterControlProgram
22
Si je peux me permettre, le code de Skurmedel est pour python 2; pour l' adapter à python 3, le changement iteritemsde itemset ajouter entre parenthèses à print. Cela pourrait empêcher des débutants comme moi de tomber sur:
AttributeError: 'dict' object has no attribute 'iteritems'et de chercher ailleurs (par exemple, l' erreur «l'objet« dict »n'a pas d'attribut« iteritems »» en essayant d'utiliser write_shp () de NetworkX pourquoi cela se produit.
Parfois, vous ne voulez pas spécifier le nombre d'arguments et souhaitez utiliser des clés pour eux (le compilateur se plaindra si un argument passé dans un dictionnaire n'est pas utilisé dans la méthode).
def manyArgs1(args):print args.a, args.b #note args.c is not used heredef manyArgs2(args):print args.c #note args.b and .c are not used hereclassArgs:pass
args =Args()
args.a =1
args.b =2
args.c =3
manyArgs1(args)#outputs 1 2
manyArgs2(args)#outputs 3
Ensuite, vous pouvez faire des choses comme
myfuns =[manyArgs1, manyArgs2]for fun in myfuns:
fun(args)
C'est un code terrible. Beaucoup mieux serait:f = lambda **dic: ' '.join(dic.get(key, 'None') for key in 'abc')
métaperture
0
Une autre façon de procéder, outre les bonnes réponses déjà mentionnées, dépend du fait que vous pouvez passer des arguments nommés facultatifs par position. Par exemple,
Réponses:
Oui. Vous pouvez utiliser
*args
comme argument non mot-clé . Vous pourrez alors passer n'importe quel nombre d'arguments.Comme vous pouvez le voir, Python décompresse les arguments en un seul tuple avec tous les arguments.
Pour les arguments de mots clés, vous devez les accepter comme un argument réel distinct, comme indiqué dans la réponse de Skurmedel .
la source
manyArgs(x = 3)
échoue avecTypeError
. La réponse de Skumedel montre la solution à cela. Le point clé est que la signature générale d'une fonction estf(*list_args, **keyword_args)
(pasf(*list_args)
).args
esttuple
.kwargs
signifie args mot-clé . Le type dekwargs
estdictionary
.for arg in args:
pour l'itération desAjout au déroulement de la publication:
Vous pouvez également envoyer plusieurs arguments de valeur-clé.
Et vous pouvez mélanger les deux:
Ils doivent être à la fois déclarés et appelés dans cet ordre, c'est-à-dire que la signature de fonction doit être * args, ** kwargs et appelée dans cet ordre.
la source
print a
avecprint(a)
etkwargs.iteritems():
aveckwargs.items()
.Si je peux me permettre, le code de Skurmedel est pour python 2; pour l' adapter à python 3, le changement
iteritems
deitems
et ajouter entre parenthèses àprint
. Cela pourrait empêcher des débutants comme moi de tomber sur:AttributeError: 'dict' object has no attribute 'iteritems'
et de chercher ailleurs (par exemple, l' erreur «l'objet« dict »n'a pas d'attribut« iteritems »» en essayant d'utiliser write_shp () de NetworkX pourquoi cela se produit.et:
la source
Ajout aux autres excellents messages.
Parfois, vous ne voulez pas spécifier le nombre d'arguments et souhaitez utiliser des clés pour eux (le compilateur se plaindra si un argument passé dans un dictionnaire n'est pas utilisé dans la méthode).
Ensuite, vous pouvez faire des choses comme
la source
le code ci-dessus sortira
Cela revient à passer des arguments variables au moyen d'un dictionnaire
la source
f = lambda **dic: ' '.join(dic.get(key, 'None') for key in 'abc')
Une autre façon de procéder, outre les bonnes réponses déjà mentionnées, dépend du fait que vous pouvez passer des arguments nommés facultatifs par position. Par exemple,
Rendements
la source