装饰器@staticmethod和@classmethod有什么区别?
1
  • openoker 回复

    也许一些例子会有帮助:注意foo, class_foostatic_foo参数的区别:

    class A(object):
        def foo(self,x):
            print "executing foo(%s,%s)"%(self,x)
    
        @classmethod
        def class_foo(cls,x):
            print "executing class_foo(%s,%s)"%(cls,x)
    
        @staticmethod
        def static_foo(x):
            print "executing static_foo(%s)"%x
    
    a=A()
    

    下面是一个对象实体调用方法的常用方式.对象实体a被隐藏的传递给了第一个参数.

    a.foo(1)
    # executing foo(<__main__.A object at 0xb7dbef0c>,1)
    

    classmethods装饰,隐藏的传递给第一个参数的是对象实体的类(class A)而不是self.

    a.class_foo(1)
    # executing class_foo(<class '__main__.A'>,1)
    

    你也可以用类调用class_foo.实际上,如果你把一些方法定义成classmethod,那么实际上你是希望用类来调用这个方法,而不是用这个类的实例来调用这个方法.A.foo(1)将会返回一个TypeError错误, A.class_foo(1)将会正常运行:

    A.class_foo(1)
    # executing class_foo(<class '__main__.A'>,1)
    

    One use people have found for class methods is to create inheritable alternative constructors.

    staticmethods来装饰,不管传递给第一个参数的是self(对象实体)还是cls(类).它们的表现都一样:

    a.static_foo(1)
    # executing static_foo(1)
    
    A.static_foo('hi')
    # executing static_foo(hi)
    

    静态方法被用来组织类之间有逻辑关系的函数.

    foo只是个函数,但是当你调用a.foo的时候你得到的不仅仅是一个函数,你得到的是一个第一个参数绑定到a的"加强版"函数.foo需要两个参数,而a.foo仅仅需要一个参数.

    a绑定了foo.下面可以知道什么叫"绑定"了:

    print(a.foo)
    # <bound method A.foo of <__main__.A object at 0xb7d52f0c>>
    

    如果使用a.class_foo,是A绑定到了class_foo而不是a.

    print(a.class_foo)
    # <bound method type.class_foo of <class '__main__.A'>>
    

    最后剩下静态方法,说到底它就是一个方法.a.static_foo只是返回一个不带参数绑定的方法.static_fooa.static_foo只需要一个参数.

    print(a.static_foo)
    # <function static_foo at 0xb7d479cc>
    

公告

AI千集是一个AIGC自动创作平台
在这里您可以获得本平台自训练的
LLM和AI绘画的模型服务
和小伙伴一起玩转AI,做自己的AI机器人
来AI千集,让你的AIGC成长更有意义
扫一扫,加入我们
公众号
有加群需求的小伙伴,请微信加qianji_ai为好友

题灵是连通AI学研和就业的桥梁
登陆小程序
获取千集AI课程和论文
挑战万道AI面试题

题灵

积分排行