如何推断 @staticmethod 所属的类?

发布于 2024-07-22 17:43:08 字数 1229 浏览 12 评论 0原文

我正在尝试实现 infer_class 函数,该函数在给定一个方法的情况下找出该方法所属的类。

到目前为止,我有这样的事情:

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)

它不适用于@staticmethod-s,因为我无法想出一种方法来实现这一点。

有什么建议么?

下面是 infer_class 的实际应用:

>>> 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 ...>

I am trying to implement infer_class function that, given a method, figures out the class to which the method belongs.

So far I have something like this:

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)

It does not work for @staticmethod-s because I was not able to come up with a way to achieve this.

Any suggestions?

Here's infer_class in 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 ...>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柒七 2024-07-29 17:43:08

那是因为静态方法实际上不是方法。 staticmethod 描述符按原样返回原始函数。 无法获取访问该函数的类。 但无论如何,没有真正的理由对方法使用静态方法,始终使用类方法。

我发现静态方法的唯一用途是将函数对象存储为类属性,而不是让它们变成方法。

That's because staticmethods really aren't methods. The staticmethod descriptor returns the original function as is. There is no way to get the class via which the function was accessed. But there is no real reason to use staticmethods for methods anyway, always use classmethods.

The only use that I have found for staticmethods is to store function objects as class attributes and not have them turn into methods.

似狗非友 2024-07-29 17:43:08

我很难让自己真正推荐这个,但它似乎确实适用于简单的情况,至少:

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

I have trouble bringing myself to actually recommend this, but it does seem to work for straightforward cases, at least:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文