2010-10-22 5 views
12

Je joue avec Python callable. Fondamentalement, vous pouvez définir une classe python et implémenter la méthode __call__ pour rendre l'instance de cette classe appelable. par exemple,Vous ne pouvez pas obtenir argspec pour les callables Python?

class AwesomeFunction(object): 
    def __call__(self, a, b): 
     return a+b 

Module inspection a une getargspec fonction, ce qui vous donne la spécification de l'argument d'une fonction. Cependant, il semble que je ne peux pas l'utiliser sur un objet appelable:

fn = AwesomeFunction() 
import inspect 
inspect.getargspec(fn) 

Malheureusement, je suis un TypeError:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.6/inspect.py", line 803, in getargspec 
    raise TypeError('arg is not a Python function') 
TypeError: arg is not a Python function 

Je pense qu'il est tout à fait regrettable que vous ne pouvez pas traiter un objet appelable en fonction , sauf si je fais quelque chose de mal ici?

+0

Merci de me rappeler l'un des moins utilisés et compris les méthodes magiques, '__call__' –

Répondre

6

Si vous avez besoin de cette fonctionnalité, il est absolument trivial d'écrire une fonction wrapper qui va vérifier pour voir si fn a un attribut __call__ et si elle le fait, passer sa fonction __call__ à getargspec.

5

Si vous regardez la définition de getargspec dans le code du module inspect sur svn.python.org. Vous verrez qu'il appelle isfunction qui se dit:

isinstance(object, types.FunctionType) 

Depuis, votre AwesomeFunction est manifestement pas une instance de types.FunctionType échoue.

Si vous voulez que cela fonctionne, vous devriez essayer ce qui suit:

inspect.getargspec(fn.__call__) 
+5

Je sais qu'il attend un type de fonction. Je ne fais que déplorer le fait que Python n'a pas conçu de manière à unifier les fonctions et les objets. – EnToutCas

+1

C'est principalement parce que Python n'est pas un langage outrageusement orienté objet (Java est mon meilleur exemple). En Java, littéralement tout est un objet, au point où la plus petite unité de source exécutable est une classe. En Python, comme un tel paradigme a été évité, oui, quelques fonctionnalités manquent, mais c'est généralement plus clair. –

+0

@EnToutCas: Écrire une proposition/un correctif. A) pourrait être accepté, ou B) abattu avec une justification qui démontre pourquoi c'est une mauvaise idée. –

0

__call__ définit quelque chose qui peut être appelé par une instance de classe. Vous ne donnez pas une fonction valide à getargspec car vous lui transmettez une instance de classe.

La différence entre __init et __call__ est ceci:

fn = AwesomeFunction() # call to __init__ 
fn(1, 2) # call to __call__ 
Questions connexes