Existe uma maneira de passar parâmetros opcionais para uma função?


133

Existe uma maneira no Python de passar parâmetros opcionais para uma função enquanto a chama e na definição da função tem algum código com base em "somente se o parâmetro opcional for passado"

Respostas:


115

A documentação do Python 2, 7.6. As definições de função oferecem algumas maneiras de detectar se um chamador forneceu um parâmetro opcional.

Primeiro, você pode usar sintaxe de parâmetro formal especial *. Se a definição da função tiver um parâmetro formal precedido por um único *, o Python preencherá esse parâmetro com quaisquer parâmetros posicionais que não correspondam aos parâmetros formais anteriores (como uma tupla). Se a definição da função tiver um parâmetro formal precedido por **, o Python preencherá esse parâmetro com qualquer parâmetro de palavra-chave que não seja correspondido pelos parâmetros formais anteriores (como um ditado). A implementação da função pode verificar o conteúdo desses parâmetros para quaisquer "parâmetros opcionais" da classificação que você deseja.

Por exemplo, aqui está uma função opt_funque recebe dois parâmetros posicionais x1e x2, e procura por outro parâmetro palavra-chave chamada "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

Segundo, você pode fornecer um valor de parâmetro padrão de algum valor como o Noneque um chamador nunca usaria. Se o parâmetro tiver esse valor padrão, você sabe que o chamador não especificou o parâmetro. Se o parâmetro tiver um valor não padrão, você sabe que veio do chamador.


7
positional_parametersé uma tupla e keyword_parametersum dicionário.
precisa saber é o seguinte

Como o python distingue formal parameters preceded by * (como isso é chamado?) De um keyword parameter? Pelo que entendi, os parâmetros de palavra-chave são especificados usando o =operador na chamada de função ( opt_fun(1,2, optional="yes")fornece um argumento de palavra-chave "yes" para uma função que antecipa, mas não exige necessariamente, o parâmetro option).
Minh Tran

Por outro lado, entendi formal parameters preceded by * simplesmente "os argumentos fornecidos pelo chamador que não correspondem aos argumentos posicionais anteriores a qualquer argumento de palavra-chave". Por exemplo, em opt_fun(1,2, "blah", 3.14, mykey="yes", myyear="2018"), "blah"e 3.14são forma arguments preceded by *porque está em entre os dois argumentos posicionais e o argumento de que utiliza o =sinal. A tupla resultante positional_parameterseria a duple: ("blah", 3.14). Isso está correto?
Minh Tran

@MinhTran, as perguntas nos comentários não são a melhor maneira de obter uma resposta no Stack Overflow. É muito melhor clicar no grande botão azul "Fazer pergunta" e escrever sua solicitação como uma "Pergunta" que outras pessoas possam "Responder". Mas para ajudá-lo, a) note que escrevi " parameter" não " parameters" para " preceded by *". O idioma permite apenas um *identifierna lista de parâmetros. b) leia docs.python.org/2/reference/… , c) leia docs.python.org/2/reference/expressions.html#calls . Desculpe, a falta de caracteres é permitida neste comentário.
Jim DeLaHunt

81
def my_func(mandatory_arg, optional_arg=100):
    print(mandatory_arg, optional_arg)

http://docs.python.org/2/tutorial/controlflow.html#default-argument-values

Acho isso mais legível do que usar **kwargs.

Para determinar se um argumento foi passado, eu uso um objeto de utilitário personalizado como o valor padrão:

MISSING = object()

def func(arg=MISSING):
    if arg is MISSING:
        ...

-Obrigado, existe uma maneira de especificar o valor padrão desse parâmetro como outra variável no código?
user1795998

sim. default_value=100; def my_func(mandatory_argument, optional_argument_with_default_value=default_value): ...
warvariuc

Isso parece mostrar como usar parâmetros opcionais, mas não como testar se um deles foi aprovado, o que o OP está pedindo.
Mawg diz restabelecer Monica

4
Na maioria dos casos, essa é a solução mais simples e direta do que a de Jim. Se você definir o valor padrão como Nenhum, poderá verificar se o parâmetro foi passado ou não. O único caso em que a solução de Jim é melhor é se é importante distinguir entre passar None como argumento e não passar um argumento.
Arnon Axelrod

19
def op(a=4,b=6):
    add = a+b
    print add

i)op() [o/p: will be (4+6)=10]
ii)op(99) [o/p: will be (99+6)=105]
iii)op(1,1) [o/p: will be (1+1)=2]
Note:
 If none or one parameter is passed the default passed parameter will be considered for the function. 

1
Existe uma maneira de passar apenas o segundo parâmetro (b) e não o primeiro (a)?
Djidiouf

4
@Djidiouf Sim, existeop(b=2)
Jürg Merlin Spaak

7

Se você deseja atribuir algum valor padrão a um parâmetro, atribua o valor em (). como (x = 10). Mas importante é o primeiro argumento obrigatório, depois o valor padrão.

por exemplo.

(y, x = 10)

mas

(x = 10, y) está errado


Obrigado, existe uma maneira de especificar o valor padrão deste parâmetro como outra variável no código?
user1795998

Sim, você pode usar algo chamado *arg **kargcomo argumentos de função. pesquise no google.
sumit

Isso parece mostrar como usar parâmetros opcionais, mas não como testar se um deles foi aprovado, o que o OP está pedindo.
Mawg diz restabelecer Monica

2

Você pode especificar um valor padrão para o argumento opcional com algo que nunca seria passado para a função e verificá-lo com o isoperador:

class _NO_DEFAULT:
    def __repr__(self):return "<no default>"
_NO_DEFAULT = _NO_DEFAULT()

def func(optional= _NO_DEFAULT):
    if optional is _NO_DEFAULT:
        print("the optional argument was not passed")
    else:
        print("the optional argument was:",optional)

desde que não o faça, func(_NO_DEFAULT)você poderá detectar com precisão se o argumento foi aprovado ou não e, diferentemente da resposta aceita, você não precisa se preocupar com os efeitos colaterais da ** notação:

# these two work the same as using **
func()
func(optional=1)

# the optional argument can be positional or keyword unlike using **
func(1) 

#this correctly raises an error where as it would need to be explicitly checked when using **
func(invalid_arg=7)

Apenas faça _NO_DEFAULT = object().
Aran-Fey

Vale a pena duas linhas extras para oferecer uma melhor introspecção. Com isso, se você executar, help(func)terá uma idéia mais clara de como o argumento é interpretado se não for passado explicitamente.
Tadhg McDonald-Jensen
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.