2017-07-26 3 views
1

J'explore une API, et en utilisant ce qui suit pour voir quelles méthodes sont disponibles sans chercher à travers tous les attributs de l'œil avec dir():Est-ce que callable (obj) tente d'appeler?

methods = [m for m in dir(kt) if callable(getattr(kt, m))] 

qui jette une exception:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Library/Python/2.7/site-packages/soco/core.py", line 103, in inner_function 
    raise SoCoSlaveException(message) 
soco.exceptions.SoCoSlaveException: The method or property "cross_fade" can only be called/used on the coordinator in a group 

Ok, donc Je ne peux pas utiliser cross_fade, c'est bien. Mais je n'ai pas essayé de l'appeler, j'essayais juste de savoir si je pouvais.

J'aurais pensé que callable() serait en mesure de vérifier en utilisant quelque chose de similaire à type(), mais il semble qu'il essaie de faire un appel et seulement attraper certains types d'exceptions.

Je reçois la même exception quand j'ai essayé type(kt.cross_fade), et quand je viens d'essayer >>> kt.cross_fade dans le terminal.

Donc je suppose qu'il y a deux questions ici: Est-ce que callable tente d'appeler? Et, qu'est-ce qui peut faire qu'une méthode "existe" mais soit complètement indisponible?

Répondre

3

callable n'essaie pas d'appeler l'objet. Il vérifie seulement que l'objet a une implémentation de l'opérateur d'appel.

L'exception se produit lors de la tentative de récupération de l'attribut en premier lieu. L'attribut attribut peut être remplacé pour faire n'importe quoi en Python, et l'attribut cross_fade de cet objet est implémenté comme property avec un décorateur only_on_master sur le getter qui déclenche une exception si vous essayez de récupérer l'attribut sur un esclave.

1

Si nous regardons le source code, nous verrons que cross_fade est en fait une propriété:

@property 
@only_on_master # Only for symmetry with the setter 
def cross_fade(self): 
    """The speaker's cross fade state. 
    True if enabled, False otherwise 
    """ 
    # ... 

À son tour, le getter est enveloppé dans only_on_master qui est l'endroit où l'exception est soulevée.