Existe uma maneira de chamar uma função Python com o número errado de argumentos sem invocar um TypeError?

StackOverflow https://stackoverflow.com/questions/933484

  •  06-09-2019
  •  | 
  •  

Pergunta

Quando você chamar uma função com o número errado de argumentos ou com um argumento de palavra-chave que não está na sua definição, você recebe um TypeError. Eu gostaria de um pedaço de código para fazer uma chamada de retorno e invocá-lo com argumentos variáveis, com base no que os suportes de retorno de chamada. Uma maneira de fazer isso seria a de, por um cb callback, cb.__code__.cb_argcount uso e cb.__code__.co_varnames, mas eu preferia abstrato que em algo como apply, mas que só se aplica aos argumentos que "fit".

Por exemplo:

 def foo(x,y,z):
   pass

 cleanvoke(foo, 1)         # should call foo(1, None, None)
 cleanvoke(foo, y=2)       # should call foo(None, 2, None)
 cleanvoke(foo, 1,2,3,4,5) # should call foo(1, 2, 3)
                           # etc.

Existe alguma coisa como esta já em Python, ou é algo que eu deveria escrever a partir do zero?

Foi útil?

Solução

Ao invés de cavar para os detalhes, você pode inspecionar assinatura da função -. você provavelmente vai querer inspect.getargspec(cb)

Exatamente como você deseja usar essa informação, e os argumentos que você tem, para chamar a função "adequadamente", não é completamente claro para mim. Assumindo por simplicidade que você só se preocupam com simples chamado args, e os valores que você gostaria de passar estão em dict d ...

args = inspect.getargspec(cb)[0]
cb( **dict((a,d.get(a)) for a in args) )

Talvez você quer algo mais sofisticado, e pode elaborar sobre o que exatamente?

Outras dicas

Esta talvez?

def fnVariableArgLength(*args, **kwargs):
    """
    - args is a list of non keywords arguments
    - kwargs is a dict of keywords arguments (keyword, arg) pairs
    """
    print args, kwargs


fnVariableArgLength() # () {}
fnVariableArgLength(1, 2, 3) # (1, 2, 3) {}
fnVariableArgLength(foo='bar') # () {'foo': 'bar'}
fnVariableArgLength(1, 2, 3, foo='bar') # (1, 2, 3) {'foo': 'bar'}

Editar Seus casos de uso

def foo(*args,*kw):
    x= kw.get('x',None if len(args) < 1 else args[0])
    y= kw.get('y',None if len(args) < 2 else args[1])
    z= kw.get('z',None if len(args) < 3 else args[2])
    # the rest of foo

foo(1)         # should call foo(1, None, None)
foo(y=2)       # should call foo(None, 2, None)
foo(1,2,3,4,5) # should call foo(1, 2, 3)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top