在类主体中调用类staticmethod?

发布于 2021-01-29 14:55:34

当我尝试从类的正文中使用静态方法,并使用内置staticmethod函数作为装饰器来定义静态方法时,如下所示:

class Klass(object):

    @staticmethod  # use as decorator
    def _stat_func():
        return 42

    _ANS = _stat_func()  # call the staticmethod

    def method(self):
        ret = Klass._stat_func() + Klass._ANS
        return ret

我收到以下错误:

Traceback (most recent call last):<br>
  File "call_staticmethod.py", line 1, in <module>
    class Klass(object): 
  File "call_staticmethod.py", line 7, in Klass
    _ANS = _stat_func() 
  TypeError: 'staticmethod' object is not callable

我了解为什么会发生这种情况(描述符绑定) ,并且可以通过_stat_func()在上次使用后手动将其转换为静态方法来解决此问题,如下所示:

class Klass(object):

    def _stat_func():
        return 42

    _ANS = _stat_func()  # use the non-staticmethod version

    _stat_func = staticmethod(_stat_func)  # convert function to a static method

    def method(self):
        ret = Klass._stat_func() + Klass._ANS
        return ret

所以我的问题是:

是否有更好的方法(如更清洁或更“ Pythonic”的方法)来实现这一目标?

关注者
0
被浏览
107
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    staticmethod对象显然具有__func__存储原始原始函数的属性(它们必须这样做)。所以这将工作:

    class Klass(object):
    
        @staticmethod  # use as decorator
        def stat_func():
            return 42
    
        _ANS = stat_func.__func__()  # call the staticmethod
    
        def method(self):
            ret = Klass.stat_func()
            return ret
    

    顺便说一句,尽管我怀疑静态方法对象具有某种存储原始功能的属性,但我对具体细节一无所知。本着教别人钓鱼而不是给他们钓鱼的精神,这就是我所做的调查,并发现了这一点(Python会话中的C&P):

    >>> class Foo(object):
    ...     @staticmethod
    ...     def foo():
    ...         return 3
    ...     global z
    ...     z = foo
    
    >>> z
    <staticmethod object at 0x0000000002E40558>
    >>> Foo.foo
    <function foo at 0x0000000002E3CBA8>
    >>> dir(z)
    ['__class__', '__delattr__', '__doc__', '__format__', '__func__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
    >>> z.__func__
    <function foo at 0x0000000002E3CBA8>
    

    在交互式会话中进行类似的挖掘(dir非常有帮助)通常可以非常快速地解决这些问题。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看