¿Hay alguna manera en Python para pasar parámetros opcionales a una función mientras la llama y en la definición de la función tiene algún código basado en "solo si se pasa el parámetro opcional"?
La documentación de Python 2, 7.6. Las definiciones de funciones le brindan un par de formas de detectar si una persona que llama proporcionó un parámetro opcional.
Primero, puede usar la sintaxis especial de parámetros formales *
. Si la definición de la función tiene un parámetro formal precedido por un solo *
, entonces Python llena ese parámetro con cualquier parámetro posicional que no coincida con los parámetros formales anteriores (como una tupla). Si la definición de la función tiene un parámetro formal precedido por**
, entonces Python rellena ese parámetro con cualquier parámetro de palabra clave que no coincida con los parámetros formales anteriores (como un dict). La implementación de la función puede verificar el contenido de estos parámetros para cualquier "parámetro opcional" del tipo que desee.
Por ejemplo, aquí es una función opt_fun
que toma dos parámetros de posición x1
y x2
, y busca otro parámetro de palabra clave denominada "opcional".
>>> def opt_fun(x1, x2, *positional_parameters, **keyword_parameters):
... if ('optional' in keyword_parameters):
... print 'optional parameter found, it is ', keyword_parameters['optional']
... else:
... print 'no optional parameter, sorry'
...
>>> opt_fun(1, 2)
no optional parameter, sorry
>>> opt_fun(1,2, optional="yes")
optional parameter found, it is yes
>>> opt_fun(1,2, another="yes")
no optional parameter, sorry
En segundo lugar, puede proporcionar un valor de parámetro predeterminado de algún valor como None
que una persona que llama nunca usaría. Si el parámetro tiene este valor predeterminado, sabe que la persona que llamó no especificó el parámetro. Si el parámetro tiene un valor no predeterminado, sabe que proviene del llamador.
positional_parameters
es una tupla ykeyword_parameters
un diccionario.formal parameters preceded by *
(¿cómo se llama esto?) De akeyword parameter
? Tal como lo entendí, los parámetros de palabras clave se especifican utilizando el=
operador en la llamada a la función (por lo queopt_fun(1,2, optional="yes")
proporciona un argumento de palabra clave "sí" para una función que anticipa, pero no necesariamente, el parámetrooption
).formal parameters preceded by *
simplemente "los argumentos proporcionados por la persona que llama que no se corresponden con los argumentos posicionales que van antes que cualquier argumento de palabras clave". Por ejemplo, inopt_fun(1,2, "blah", 3.14, mykey="yes", myyear="2018")
,"blah"
y3.14
areforma arguments preceded by *
porque está entre los dos argumentos posicionales y el argumento que usa el=
signo. La tupla resultantepositional_parameter
sería el binario:("blah", 3.14)
. ¿Es esto correcto?parameter
" no "parameters
" para "preceded by *
". El idioma permite solo uno*identifier
en la lista de parámetros. b) lea docs.python.org/2/reference/… , c) lea docs.python.org/2/reference/expressions.html#calls . Lo sentimos, quedando sin caracteres permitidos en este comentario.http://docs.python.org/2/tutorial/controlflow.html#default-argument-values
Esto me parece más legible que usarlo
**kwargs
.Para determinar si se pasó un argumento, utilizo un objeto de utilidad personalizado como valor predeterminado:
fuente
default_value=100; def my_func(mandatory_argument, optional_argument_with_default_value=default_value): ...
fuente
op(b=2)
Si desea dar un valor predeterminado a un parámetro, asigne un valor en (). como (x = 10). Pero lo importante es primero debe argumento obligatorio luego valor predeterminado.
p.ej.
(y, x = 10)
pero
(x = 10, y) está mal
fuente
*arg
**karg
como argumentos de función. buscar en Google.Puede especificar un valor predeterminado para el argumento opcional con algo que nunca pasaría a la función y verificarlo con el
is
operador:entonces, siempre que no lo haga
func(_NO_DEFAULT)
, puede detectar con precisión si el argumento fue aprobado o no, y a diferencia de la respuesta aceptada, no tiene que preocuparse por los efectos secundarios de la notación **:fuente
_NO_DEFAULT = object()
.help(func)
, obtiene una idea más clara de cómo se interpreta el argumento si no se pasa explícitamente.