Frage

Ich versuche infer_class Funktion, die, da ein Verfahren, die Klasse findet heraus, zu implementieren, zu der die Methode gehört.

Bisher habe ich so etwas wie folgt aus:

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)

Es funktioniert nicht für @ static-s, weil ich nicht in der Lage war, einen Weg zu kommen, dies zu erreichen.

Irgendwelche Vorschläge?

Hier ist infer_class in Aktion:

>>> 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 ...>
War es hilfreich?

Lösung

Das ist, weil staticmethods sind wirklich nicht Methoden. Der static Deskriptor gibt die ursprüngliche Funktion gibt. Es gibt keine Möglichkeit, die Klasse zu erhalten, über die die Funktion ausgewählt wurde. Aber es gibt keinen wirklichen Grund sowieso staticmethods für Methoden zu verwenden, immer Class verwenden.

Die einzige Anwendung, die ich für staticmethods gefunden haben, ist Funktionsobjekte als Klassenattribute zu speichern und sie nicht in die Methoden wenden müssen.

Andere Tipps

Ich habe Schwierigkeiten zu bringen, ihn zu wirklich empfehlen diese, aber es scheint für einfache Fälle zu arbeiten, zumindest:

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top