python - 有人可以解释一下 staticmethod 的源代码在 python 中是如何工作的吗

标签 python decorator static-methods python-decorators python-internals

首先,我了解装饰器通常是如何工作的。我知道 @staticmethod 剥离了签名中的实例参数,使

class C(object):
    @staticmethod
    def foo():
        print 'foo'
C.foo    //<function foo at 0x10efd4050>
C().foo  //<function foo at 0x10efd4050>

有效。

但是,我不明白staticmethod 的sourcec 代码是如何做到这一点的。

在我看来,当在 staticmethod 中包装方法 foo 时,会实例化 staticmethod 的一个实例,然后一些魔法 发生,使 C.foo() 合法。

那么..那些魔法会发生什么? staticmethod 做了什么?

我知道 SO 上关于 staticmethods 的大量主题,但没有一个能解决我的疑虑。但也许我没有击中魔法关键字。如果是这样,请告诉我。

如需staticmethod源码请引用https://hg.python.org/cpython/file/c6880edaf6f3/Objects/funcobject.c

最佳答案

staticmethod 对象是一个 descriptor .您缺少的神奇之处在于,Python 在将对象作为类或实例的属性访问时会调用 __get__ 方法。

因此,以 C.foo 的形式访问对象会导致 Python 将其转换为 C.__dict__['foo'].__get__(None, C),而 instance_of_C.foo 变为 type(instace_of_C).__dict__['foo'].__get__(instance_of_C, type(instance_of_C))

staticmethod 对象是 defined in C code ,但在 Python 中的等价物是:

class staticmethod(object):
    def __init__(self, callable):
        self.f = callable
    def __get__(self, obj, type=None):
        return self.f
    @property
    def __func__(self):
        return self.f

其中 self.f 是原始包装函数。

所有这些都是必需的,因为函数本身也是描述符;它是为您提供方法对象的描述符协议(protocol)(有关更多详细信息,请参见 python bound and unbound method object)。因为他们也有一个 __get__ 方法,没有 staticmethod 对象包装函数,一个 functionobj.__get__ 调用产生一个方法对象,传入一个 self 参数。

还有一个classmethod,它使用descriptor.__get__的第二个参数来给类绑定(bind)一个函数,然后还有property 对象,它将绑定(bind)直接转换为函数调用。参见 How does the @property decorator work? .

关于python - 有人可以解释一下 staticmethod 的源代码在 python 中是如何工作的吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31916048/

相关文章:

python - 广播 NumPy 数组时实际发生了什么

Angular |将服务注入(inject)装饰器

静态方法的 C++ 链接器问题

java - 访问java类的方法的最佳方法是创建对象或使方法成为静态类型?

python - 使用 xlwings 在 Excel 中插入图像

python - 如何使用大于 6GB 的 numpy 数组训练模型?

python - Alembic 无法识别 False 默认值

python - 如何将自定义装饰器添加到结构任务

django - 为什么 Django 中不再推荐永久链接装饰器?

Java:程序启动时出现 ExceptionInInitializerError