zoukankan      html  css  js  c++  java
  • Python中的@staticmethod和@classmethod的区别

    一直搞不明白,类方法和静态方法的区别,特意研究了一下,跟大家分享一下。

    为了方便大家了解两者的差别,以下的示例代码将有助于发现其中的差别:

    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时,对象实例的类作为第一个参数而不是隐式传递self。

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

    您也可以class_foo使用该类进行调用。

    实际上,如果您将某些东西定义为类方法,则可能是因为您打算从类而不是从类实例调用它。

    A.foo(1)本来会引发TypeError,但A.class_foo(1)效果很好:

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

    人们发现类方法的一种用途是创建可继承的替代构造函数。

    使用staticmethods时,self(对象实例)和 cls(类)都不会隐式传递为第一个参数。它们的行为类似于普通函数,只是您可以从实例或类中调用它们:

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

    特别注意此句:

    静态方法用于对与类之间具有某种逻辑联系的函数分组。

    foo只是一个函数,但是当您调用a.foo它时,不仅获得该函数,还会获得该函数的“部分应用”版本,该对象实例a绑定为该函数的第一个参数。foo期望有2个参数,而a.foo只期望有1个参数。

    a势必到foo。这就是下面的术语“绑定”的含义:

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

    与a.class_foo,a不绑定class_foo,而是与类A绑定class_foo。

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

    在这里,使用静态方法,即使它是一种方法,也a.static_foo只是返回一个没有绑定参数的良好的'ole函数。static_foo期望有1个参数,也 a.static_foo期望有1个参数。

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

    当然,当您static_foo使用类进行调用时,也会发生同样的事情A。

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

    总结一下彼此的调用区别:

    e9c9bb5d9285c7eae68b281b8ab094a0.png

    本文首发于BigYoung小站

  • 相关阅读:
    20145334赵文豪 《信息安全系统设计基础》第2周学习总结
    20145334赵文豪《信息安全系统设计基础》第1周学习总结
    关于第五周大家学习问题的总结
    20145334 第五次 java 实验报告
    20145334 《Java程序设计》第10周学习总结
    实验四 Android开发基础
    # 20145334 《Java程序设计》第9周学习总结
    20145334实验三《敏捷开发与XP实践》
    实验二:面向对象设计
    程序的机器级表示内容补充及扩展
  • 原文地址:https://www.cnblogs.com/bigyoung/p/13213318.html
Copyright © 2011-2022 走看看