【问题标题】:staticmethod from function object. Why don't I need to staticmethod it?来自函数对象的静态方法。为什么我不需要静态方法呢?
【发布时间】:2020-11-23 05:57:43
【问题描述】:

让我们反事实地假设我有充分的理由想要将内置 print 设为某个类的静态方法。

我的直觉显然是错误的,我需要声明它是静态的,像

class sm:
    p = staticmethod(print)

相对

class no_sm:
    p = print

但似乎两者都可以正常工作。

a = sm()
b = no_sm()

a.p("hello")
b.p("hello")

打印

hello
hello

为什么它只是起作用,两者之间有什么区别?

相关:Why use staticmethod instead of no decorator at all

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    对于大多数普通函数,它们通过描述符协议 (__get__),因此当以您的方式附加到类时,它们需要特殊装饰。

    举个例子:

    def f():
        print('hi')
    
    class C:
        f = f
    
    class D:
        f = staticmethod(f)
    

    在这种情况下C().f() 错误:

    >>> C().f()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: f() takes 0 positional arguments but 1 was given
    

    那是因为它通过了:

    >>> C.f.__get__(C())()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: f() takes 0 positional arguments but 1 was given
    

    但你会注意到,print 没有 __get__ 这样的属性:

    >>> hasattr(print, '__get__')
    

    它甚至有不同的类型!

    >>> type(print)
    <class 'builtin_function_or_method'>
    >>> type(f)
    <class 'function'>
    

    所以答案是:print(与其他 C 函数一起)未经特殊处理不参与方法描述符协议,因此它们充当正常的可调用对象,无需附加 self

    【讨论】:

    • 所以,基本上我选择了一个糟糕的测试用例。我不知道内置函数与纯 Python 函数有如此根本的不同。 Python 橱柜中的另一个骨架......无论如何,知道非常有用。谢谢!
    猜你喜欢
    • 2014-11-30
    • 1970-01-01
    • 2011-03-02
    • 2010-09-29
    • 1970-01-01
    • 2014-07-18
    • 2023-03-25
    • 2015-10-07
    • 2012-12-28
    相关资源
    最近更新 更多