Determina se è stato passato un parametro denominato
-
05-07-2019 - |
Domanda
Vorrei sapere se è possibile determinare se un parametro di funzione con un valore predefinito è stato passato in Python. Ad esempio, come funziona dict.pop?
>>> {}.pop('test')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'pop(): dictionary is empty'
>>> {}.pop('test',None)
>>> {}.pop('test',3)
3
>>> {}.pop('test',NotImplemented)
NotImplemented
In che modo il metodo pop determina che la prima volta che non è stato passato un valore di ritorno predefinito? È qualcosa che può essere fatto solo in C?
Grazie
Soluzione
Immagino che intendi "argomento parola chiave", quando dici "parametro nominato". dict.pop ()
non accetta l'argomento della parola chiave, quindi questa parte della domanda è discutibile.
>>> {}.pop('test', d=None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: pop() takes no keyword arguments
Detto questo, il modo per rilevare se è stato fornito un argomento è utilizzare la sintassi * args
o ** kwargs
. Ad esempio:
def foo(first, *rest):
if len(rest) > 1:
raise TypeError("foo() expected at most 2 arguments, got %d"
% (len(rest) + 1))
print 'first =', first
if rest:
print 'second =', rest[0]
Con un po 'di lavoro, e usando anche la sintassi ** kwargs
è possibile emulare completamente la convenzione di chiamata python, dove gli argomenti possono essere forniti per posizione o per nome e argomenti forniti più volte (per posizione e nome) causa un errore.
Altri suggerimenti
La convenzione prevede spesso di utilizzare arg = None
e di utilizzare
def foo(arg=None):
if arg is None:
arg = "default value"
# other stuff
# ...
per verificare se è stato superato o meno. Consentire all'utente di passare None
, che sarebbe interpretato come se l'argomento fosse non passato.
Puoi farlo in questo modo:
def isdefarg(*args):
if len(args) > 0:
print len(args), "arguments"
else:
print "no arguments"
isdefarg()
isdefarg(None)
isdefarg(5, 7)
Consulta la documentazione di Python su chiamate per informazioni complete.
def f(one, two=2):
print "I wonder if", two, "has been passed or not..."
f(1, 2)
Se questo è il significato esatto della tua domanda, penso che non ci sia modo di distinguere tra un 2 che era nel valore predefinito e un 2 che è stato passato. Non ho trovato il modo di ottenere tale distinzione nemmeno nell'ispezione modulo.
Non sono sicuro di comprendere appieno cosa desideri; tuttavia:
def fun(arg=Ellipsis):
if arg is Ellipsis:
print "No arg provided"
else:
print "arg provided:", repr(arg)
fa quello che vuoi? Altrimenti, come altri hanno suggerito, dovresti dichiarare la tua funzione con la sintassi * args, ** kwargs
e controllare nel dict di kwargs l'esistenza del parametro.