Python的classmethod如何决定它能成为一个「类装饰器」?

 看不见的风2502871717 发布于 2022-10-28 22:08

经常使用@classmethod,但是对它的原理不甚明白,函数装饰器原理不是很复杂

1 那么classmethod作为类装饰器,其作用流程是怎样的?

classmethod源码

class classmethod(object):
    """
    classmethod(function) -> method
    
    Convert a function to be a class method.
    
    A class method receives the class as implicit first argument,
    just like an instance method receives the instance.
    To declare a class method, use this idiom:
    
      class C:
          def f(cls, arg1, arg2, ...): ...
          f = classmethod(f)
    
    It can be called either on the class (e.g. C.f()) or on an instance
    (e.g. C().f()).  The instance is ignored except for its class.
    If a class method is called for a derived class, the derived class
    object is passed as the implied first argument.
    
    Class methods are different than C++ or Java static methods.
    If you want those, see the staticmethod builtin.
    """
    def __getattribute__(self, name): # real signature unknown; restored from __doc__
        """ x.__getattribute__('name') <==> x.name """
        pass

    def __get__(self, obj, type=None): # real signature unknown; restored from __doc__
        """ descr.__get__(obj[, type]) -> value """
        pass

    def __init__(self, function): # real signature unknown; restored from __doc__
        pass

    @staticmethod # known case of __new__
    def __new__(S, *more): # real signature unknown; restored from __doc__
        """ T.__new__(S, ...) -> a new object with type S, a subtype of T """
        pass

    __func__ = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
2 个回答
  • 你这段源码是哪里看到的?classmethod 应该是 built-in 用 C 写的吧,你贴的这段更像是 Python 模拟的版本。

    真的源码:https://hg.python.org/cpython/file/69b41...

    2022-10-30 03:05 回答
  • 这个链接解释的不错,你看下这里
    http://stackoverflow.com/questions/16774...

    Python文档里关于descriptor的说明有
    descriptor

    Any new-style object which defines the methods __get__(), __set__(), or __delete__().
    When a class attribute is a descriptor, its special binding behavior is triggered upon attribute lookup. Normally,
    using a.b to get, set or delete an attribute looks up the object named b in the class dictionary for a,
    but if b is a descriptor, the respective descriptor method gets called. Understanding descriptors is a key to
    a deep understanding of Python because they are the basis for many features including functions, methods,
    properties, class methods, static methods, and reference to super classes.
    For more information about descriptors’ methods, see descriptors.
    

    所以对于classmethod封装的声明,等同于

     class MyTest(object):
        @classmethod
        def sayHello(cls):
            print "sayHello"
    
    
    MyTest.sayHello()
    
    cm = classmethod(MyTest)
    cm.__get__(None, dict).im_func.sayHello()
    2022-10-30 03:09 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有