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>
总结一下彼此的调用区别:

本文首发于BigYoung小站
Python中的@staticmethod和@classmethod的区别的更多相关文章
- Python中的staticmethod和classmethod
谈谈Python中的staticmethod和classmethod 首先值得说明的是staticmethod和classmethod都是python中定义的装饰器,用的时候需要在前面加@ 即@sta ...
- (译文)Python中的staticmethod与classmethod
原文是stackoverflow的一则高票回答,原文链接 可能之前也有人翻译过,但是刚好自己也有疑惑,所以搬运一下,个人水平有限所以可能翻译存在误差,欢迎指正(如侵删). 尽管classmethod和 ...
- 基于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 ...
- python中import和from...import...的区别
python中import和from...import...的区别: 只用import时,如import xx,引入的xx是模块名,而不是模块内具体的类.函数.变量等成员,使用该模块的成员时需写成xx ...
- 转发 python中file和open有什么区别
python中file和open有什么区别?2008-04-15 11:30地痞小流氓 | 分类:python | 浏览3426次python中file和open有什么区别?都是打开文件,说的越详细越 ...
- 关于python中的staticmethod
python中的staticmethod 主要是方便将外部函数集成到类体中,美化代码结构,重点在不需要类实例化的情况下调用方法 如果你去掉staticmethod,在方法中加self也可以通过实例化访 ...
- Python中str()与repr()函数的区别——repr() 的输出追求明确性,除了对象内容,还需要展示出对象的数据类型信息,适合开发和调试阶段使用
Python中str()与repr()函数的区别 from:https://www.jianshu.com/p/2a41315ca47e 在 Python 中要将某一类型的变量或者常量转换为字符串对象 ...
- python中静态方法(@staticmethod)和类方法(@classmethod)的区别
一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法. 而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用. 这有利于组织代码,把某些应 ...
- 【开发者笔记】python中的类方法(@classmethod)和静态方法(@staticmethod)
在java.c#等高级语言中我们用static来定义静态方法和静态变量,那么在python中如何定义静态方法和静态变量呢. python提供了@classmethod和@staticmethod来定义 ...
随机推荐
- Java实现 LeetCode 75 颜色分类
75. 颜色分类 给定一个包含红色.白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色.白色.蓝色顺序排列. 此题中,我们使用整数 0. 1 和 2 分别表示红 ...
- Java实现 LeetCode 30 串联所有单词的子串
30. 串联所有单词的子串 给定一个字符串 s 和一些长度相同的单词 words.找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置. 注意子串要与 words 中的单词完全匹配, ...
- Android getMeasuredHeight()与getHeight()的区别
getMeasuredHeight()返回的是原始测量高度,与屏幕无关 getHeight()返回的是在屏幕上显示的高度 实际上在当屏幕可以包裹内容的时候,他们的值是相等的,只有当view超出屏幕后, ...
- Andorid中写文件后在电脑上看不到的解决办法
每次通过输出流往SD卡写入文件,连接上电脑,用MTP的方式模拟一个移动磁盘,打开磁盘却没有这样一个文件,而通过adb的方式查看就有,造成这个现象的原因是,每次写入之后,MTP的数据库并没有更新,因为更 ...
- Postsharp简单试用——在业务逻辑类上添加日志记录
1.首先添加PostSharp引用 2.添加特性(Attribute)类 [Serializable] [AttributeUsage(AttributeTargets.Method, AllowMu ...
- C#数据结构与算法系列(一):介绍
1.介绍 数据结构:是指相互之间存在一种或多种特定关系的数据元素的集合用计算机存储.组织数据的方式.数据结构分别为逻辑结构.(存储)物理结构和数据的运算三个部分. 数据结构包括:线性结构和非线性结构. ...
- Install Centos7 on VirtualBox in mac
Step 1:准备虚拟机及镜像 下载合适的Virtual Box版本 官方下载链接:https://www.virtualbox.org/wiki/Downloads 这里选择的版本是:https:/ ...
- Mysql 视图用途、使用场景、性能问题及使用注意事项
原文:https://blog.csdn.net/chuangxin/article/details/84574557 <SQLite权威指南>中作者是这么定义视图的:视图即是虚拟表,也称 ...
- 我要穿越,干翻 “烂语言” JavaScript!
更多精彩文章,尽在码农翻身 我是一个线程 TCP/IP之大明邮差 一个故事讲完Https CPU 阿甘 Javascript: 一个屌丝的逆袭 微服务把我坑了 如何降低程序员的工资? 程序员,你得选准 ...
- Eplan显示项目属性的编号设置方法
打开eplan,点击选项->设置->用户->显示->用户界面.在“显示标识性的编号”前打勾.