Python中的方法、`classmethod`和`staticmethod`是如何实现的?

37 投票
2 回答
11965 浏览
提问于 2025-04-16 21:27

在Python中,方法什么时候会变成一个get属性呢?是当它们在类里定义的时候吗?为什么Python允许我定义一个没有任何参数的方法(连第一个self参数都没有)呢?

我知道怎么使用classmethodstaticmethod,而且我知道它们是内置函数,但当一个函数被这样装饰后,会发生什么呢?

总的来说,我想了解一下在类定义和类构造之间发生的“魔法”。

2 个回答

14

作为参考,来自 @JAB 的回答中的 第一个链接

使用非数据描述符协议,纯 Python 版本的 staticmethod() 看起来是这样的:

class StaticMethod(object):
    "Emulate PyStaticMethod_Type() in Objects/funcobject.c"

    def __init__(self, f):
        self.f = f

    def __get__(self, obj, objtype=None):
        return self.f

...

使用非数据描述符协议,纯 Python 版本的 classmethod() 看起来是这样的:

class ClassMethod(object):
    "Emulate PyClassMethod_Type() in Objects/funcobject.c"

    def __init__(self, f):
        self.f = f

    def __get__(self, obj, klass=None):
        if klass is None:
            klass = type(obj)
        def newfunc(*args):
            return self.f(klass, *args)
        return newfunc
35

看看这个。

https://docs.python.org/3/howto/descriptor.html#class-methods

你还可以查看类方法和静态方法对象的源代码,文件名是funcobject.c:

http://hg.python.org/cpython/file/69b416cd1727/Objects/funcobject.c

类方法对象的定义从第694行开始,而静态方法对象的定义从第852行开始。(我觉得有点搞笑的是,funcobject.c里有“method”这个标题的项目,而methodobject.c也存在。)

撰写回答