C'è un modo per richiamare una funzione Python con il numero errato di argomenti senza invocare un TypeError?

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

  •  06-09-2019
  •  | 
  •  

Domanda

Quando si richiama una funzione con il numero errato di argomenti o con un argomento parola chiave che non è nella sua definizione, si ottiene un TypeError. Mi piacerebbe un pezzo di codice per prendere un callback e invocare con argomenti variabili, in base a ciò supporta la richiamata. Un modo per farlo sarebbe quello di, per un cb callback, utilizzare cb.__code__.cb_argcount e cb.__code__.co_varnames, ma vorrei piuttosto astratto che in qualcosa di simile apply, ma che si applica solo gli argomenti che "fit".

Ad esempio:

 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.

C'è qualcosa di simile già in Python, o è qualcosa che avrei dovuto scrivere da zero?

È stato utile?

Soluzione

Invece di scavare verso il basso nei dettagli voi stessi, potete ispezionare firma della funzione - probabilmente si desidera inspect.getargspec(cb)

.

Esattamente come si desidera utilizzare queste informazioni, e le args si possiede, per richiamare la funzione "correttamente", non è del tutto chiaro per me. Assumendo per semplicità che vi interessa soltanto semplici args di nome, ed i valori che desideri passare sono in dict d ...

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

Forse si vuole qualcosa di più elaborato, e può elaborare esattamente che cosa?

Altri suggerimenti

Questo forse?

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'}

Modifica Le tue casi d'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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top