python中@classmethod @staticmethod区别

Python中3种方式定义类方法, 常规方式, @classmethod修饰方式, @staticmethod修饰方式.

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

1.定义方式

普通的类方法foo()需要通过self参数隐式的传递当前类对象的实例。 @classmethod修饰的方法class_foo()需要通过cls参数传递当前类对象。@staticmethod修饰的方法定义与普通函数是一样的。

self和cls的区别不是强制的,只是PEP8中一种编程风格,slef通常用作实例方法的第一参数,cls通常用作类方法的第一参数。即通常用self来传递当前类对象的实例,cls传递当前类对象。

2.绑定对象

foo方法绑定对象A的实例,class_foo方法绑定对象A,static_foo没有参数绑定。
>>> print(a.foo)
<bound method A.foo of <__main__.A object at 0x0278B170>>
>>> print(a.class_foo)
<bound method A.class_foo of <class '__main__.A'>>
>>> print(a.static_foo)
<function A.static_foo at 0x02780390>

3.调用方式

foo可通过实例a调用,类对像A直接调用会参数错误。

>>> a.foo(1)
executing foo(<__main__.A object at 0x0278B170>,1)
self: <__main__.A object at 0x0278B170>
>>> A.foo(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() missing 1 required positional argument: 'x'

但foo如下方式可以使用正常,显式的传递实例参数a。

>>> A.foo(a, 1)
executing foo(<__main__.A object at 0x0278B170>,1)
self: <__main__.A object at 0x0278B170>

class_foo通过类对象或对象实例调用。

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

static_foo通过类对象或对象实例调用。

>>> A.static_foo(1)
executing static_foo(1)
>>> a.static_foo(1)
executing static_foo(1)

4.继承与覆盖普通类函数是一样的。

class B(A):
pass
b = B()
b.foo(1)
b.class_foo(1)
b.static_foo(1)
# executing foo(<__main__.B object at 0x007027D0>,1)
# self: <__main__.B object at 0x007027D0>
# executing class_foo(<class '__main__.B'>,1)
# cls: <class '__main__.B'>
# executing static_foo(1)

问题:@staticmethod修饰的方法函数与普通的类外函数,为什么不直接使用普通函数?
@staticmethod是把函数嵌入到类中的一种方式,函数就属于类,同时表明函数不需要访问这个类。通过子类的继承覆盖,能更好的组织代码。

参考:What is the difference between @staticmethod and @classmethod in Python?

@staticmethod 和@classmethod区别的更多相关文章

  1. python中 staticmethod与classmethod区别

    staticmethod与classmethod区别 参考 https://stackoverflow.com/questions/136097/what-is-the-difference-betw ...

  2. @staticmethod和@classmethod区别

    转载自: https://www.cnblogs.com/wyongbo/p/python_static_method.html https://www.cnblogs.com/champaign/p ...

  3. python(三)@staticmethod和@classmethod使用和区别

    转载自[1] 一般要用某个类的方法,先要实例这个类. 但是可以通过@staticmethod和@classmethod,直接用“类.方法()”来调用这个方法. 而 @staticmethod和@cla ...

  4. (转)关于python3中staticmethod(静态方法)classmethod(类方法)实例方法的联系和区别

    原文:http://dmcoders.com/2017/08/30/pythonclass/ https://zhuanlan.zhihu.com/p/28010894------正确理解Python ...

  5. @staticmethod和@classmethod的作用与区别

    一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法. 而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用. 这有利于组织代码,把某些应 ...

  6. Python - 静态函数(staticmethod), 类函数(classmethod), 成员函数 区别(完全解析)

    原文地址:http://blog.csdn.net/caroline_wendy/article/details/23383995 还有一篇:http://blog.csdn.net/carolzha ...

  7. 基于python中staticmethod和classmethod的区别(详解)

    例子 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 class A(object):   def foo(self,x):     print "executing foo ...

  8. 【Python】@staticmethod和@classmethod的作用与区别

    前言 Python其实有3个方法,即静态方法(staticmethod),类方法(classmethod)和实例方法,一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法.而使用@static ...

  9. 飘逸的python - @staticmethod和@classmethod的作用与区别

    一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法. 而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用. 这有利于组织代码,把某些应 ...

随机推荐

  1. 第01章 开发准备(对最新版的RN进行了升级)1-3+项目结构介绍

  2. 对输入字符进行HTML转义 OR  去HTML标签

    /** * 对输入字符进行HTML转义 * @param mixed $data */ public static function escape($data) { if(is_array($data ...

  3. 520. Detect Capital判断单词有效性

    [抄题]: Given a word, you need to judge whether the usage of capitals in it is right or not. We define ...

  4. ROS naviagtion analysis: costmap_2d--StaticLayer

    博客转载自:https://blog.csdn.net/u013158492/article/details/50493246 从UML中能够看到,StaticLayer主要是在实现Layer层要求实 ...

  5. Hyperledger Fabric1.0 整体结构

    整体结构 Hyperledger Fabric 在 1.0 中,架构已经解耦为三部分: fabric-peer:主要起到 peer 作用,包括 endorser.committer 两种角色: fab ...

  6. cakephp中sql查询in

    $list = $this->Capital->find('all', array('conditions'=>array('remark in '=>array('银联支付' ...

  7. What’s the Difference Between a Value Provider and Model Binder?

    ASP.NET MVC 3 introduced the ability to bind an incoming JSON request to an action method parameter, ...

  8. 编写高质量代码改善C#程序的157个建议——建议10: 创建对象时需要考虑是否实现比较器

    建议10: 创建对象时需要考虑是否实现比较器 有对象的地方就会存在比较,在.NET的世界中也一样.举个最简单的例子,在UI中,有一个10个人的Salary列表.根据排序的需要,列表要支持针对基本工资来 ...

  9. [转]windows7远程桌面连接失败:发生身份验证错误。要求的函数不受支持

    转至:https://jingyan.baidu.com/article/d169e18604ca86436611d821.html 系统升级后出现远程连接报错,“发生身份验证错误.要求的函数不受支持 ...

  10. EBS取Web字段SQL操作文档

    1)  安全性—>责任-à定义 在这个路径下,输入责任名称,可以查询这个责任的请求组的名称 2)  organization_id 和 org_id的功能 3)  查找网页上的字段 Naviga ...