7
votes

Python: StaticMethod décoré reçoit une méthode non appelable

J'ai un petit problème à décorer une méthode statique en Python. Je pense que le code suivant représente le mieux mon problème: xxx

Cela semble être un bug. J'imagine qu'il se pose parce que lorsque la méthode foo.bar est transmise au décorateur, il s'agit d'une fonction, pas d'une méthode. C'est la seule raison pour laquelle je peux voir pour ne pas être appelable, car si nous décorions une fonction standard, il n'est pas appelable, comme indiqué ci-dessous. xxx

est-ce un True Bug dans la mise en œuvre du décorateur StaticMethod et / ou y a-t-il des solutions de contournement simples? J'ai pensé à écrire un décorateur à asignez un attribut __ __ , mais je ne sais pas comment appelable est mis en œuvre, donc je ne peux pas évaluer la réussite d'une telle méthode .


2 commentaires

Notez que vous devez utiliser de nouvelles classes de style pour un staticmethod à appeler également sur des instances, car cela utilise des descripteurs.


Pour le faire fonctionner, changez simplement l'ordre des descripteurs.


3 Réponses :


4
votes

Eh bien, si vous considérez cela un bug ou non, c'est documenté :

Méthode statique Les objets fournissent un moyen de vaincre la transformation de Objets de fonction aux objets de la méthode décrit ci-dessus. Une méthode statique objet est une enveloppe autour de tout autre objet, généralement une méthode définie par l'utilisateur objet. Lorsqu'un objet de méthode statique est extrait d'une classe ou d'une classe instance, l'objet est effectivement renvoyé est l'objet emballé, qui n'est pas sous réserve de toute nouvelle transformation. Les objets de méthode statique ne sont pas eux-mêmes appelables, bien que le Les objets qu'ils enveloppent sont généralement. Statique Les objets de la méthode sont créés par le Constructeur StaticMethod intégré ().


0 commentaires

6
votes

Méthodes sont fonctions. Mais staticmethod Les objets ne sont pas. Ils sont Descriptors , donc il y a une magie supplémentaire qui vous donne une appelable lorsque vous Accédez comme cls.static_method , mais cette magie ne peut rien cacher lorsque vous utilisez (c.-à-d. Passer à décorateur) static_method à l'intérieur du corps de CLS . Vous ne pouvez pas vraiment pirater votre chemin autour de cela, du moins pas proprement. Une solution beaucoup plus simple est la réorganisation des décorateurs tels que staticmethod est appliqué en dernier - c'est-à-dire le mettre au sommet, au-dessus de tous les autres décorateurs.


0 commentaires

1
votes

J'ai écrit ma propre implémentation de staticmethod que est appelable appelable et cela semble résoudre ce problème bien. XXX Ceci ne " t Utilisez le protocole de descripteur et, comme cela se comporte très différemment que celui de StaticMethod en interne, toutefois, dans la pratique, cela rend les fonctions appelables comme attributs de classe, des attributs d'instance et même comme des attributs de fonction (c'est-à-dire si vous avez Enveloppé votre classe dans une fonction de décoration, cette implémentation de StaticMethod vous permettra toujours d'appeler vos méthodes statiques en tant qu'attributs de la fonction d'emballage).


0 commentaires