python 中的 staticmethod 和 classmethod 是不可调用的吗?

Are staticmethod and classmethod in python not callable?

我正在写一个元class来强制class和实例方法的文档字符串。令我惊讶的是,staticmethod 和 classmethod 与实例方法不同 callable。我不确定为什么?

class MyMeta(type):
    def __new__(cls, name, parents, attrs):
        print(cls, name, parents, attrs)

        if "__doc__" not in attrs:
            raise TypeError("Please define class level doc string!!!")

        for key, value in attrs.items():
            if callable(value) and value.__doc__ is None:
                raise TypeError("Please define def level doc string!!!")

        return super().__new__(cls, name, parents, attrs)

class A(metaclass=MyMeta):
    """This is API doc string"""
    def hello(self):
        """"""
        pass

    def __init__(self):
        """__init__ Method"""
        pass

    @classmethod
    def abc(cls):
        pass

我不明白为什么它们不可调用?如果我不为他们定义文档字符串,他们似乎通过了我的检查。

它们不可调用。 classmethodstaticmethoddescriptor objects, and they do not implement __call__. The HOWTO 实际上给出了如何在纯 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

注意,函数对象也是描述符。它们恰好是可调用的描述符。