Question

Je suis en train de mettre en œuvre la fonction infer_class que, étant donné une méthode, figure la classe à laquelle appartient la méthode.

Jusqu'à présent, j'ai quelque chose comme ceci:

import inspect

def infer_class(f):
    if inspect.ismethod(f):
        return f.im_self if f.im_class == type else f.im_class
    # elif ... what about staticmethod-s?
    else:
        raise TypeError("Can't infer the class of %r" % f)

Il ne fonctionne pas pour @ staticmethod-s parce que je ne pouvais pas trouver un moyen d'y parvenir.

Toutes les suggestions?

Ici se infer_class en action:

>>> class Wolf(object):
...     @classmethod
...     def huff(cls, a, b, c):
...         pass
...     def snarl(self):
...         pass
...     @staticmethod
...     def puff(k,l, m):
...         pass
... 
>>> print infer_class(Wolf.huff)
<class '__main__.Wolf'>
>>> print infer_class(Wolf().huff)
<class '__main__.Wolf'>
>>> print infer_class(Wolf.snarl)
<class '__main__.Wolf'>
>>> print infer_class(Wolf().snarl)
<class '__main__.Wolf'>
>>> print infer_class(Wolf.puff)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in infer_class
TypeError: Can't infer the class of <function puff at ...>
Était-ce utile?

La solution

C'est parce que staticmethods ne sont vraiment pas des méthodes. Le descripteur de staticmethod retourne la fonction initiale est. Il n'y a pas moyen d'obtenir la classe via laquelle la fonction a été consulté. Mais il n'y a aucune raison d'utiliser staticmethods pour les méthodes de toute façon, utilisez toujours classmethods.

La seule utilisation que je l'ai trouvé pour staticmethods est de stocker des objets de fonction comme attributs de classe et pas les transformer en méthodes.

Autres conseils

J'ai du mal à me mettre à réellement recommander , mais il ne semble pas fonctionner pour les cas simples, au moins:

import inspect

def crack_staticmethod(sm):
    """
    Returns (class, attribute name) for `sm` if `sm` is a
    @staticmethod.
    """
    mod = inspect.getmodule(sm)
    for classname in dir(mod):
        cls = getattr(mod, classname, None)
        if cls is not None:
            try:
                ca = inspect.classify_class_attrs(cls)
                for attribute in ca:
                    o = attribute.object
                    if isinstance(o, staticmethod) and getattr(cls, sm.__name__) == sm:
                        return (cls, sm.__name__)
            except AttributeError:
                pass
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top