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 810 黑板异或游戏 (分析)
810. 黑板异或游戏 一个黑板上写着一个非负整数数组 nums[i] .小红和小明轮流从黑板上擦掉一个数字,小红先手.如果擦除一个数字后,剩余的所有数字按位异或运算得出的结果等于 0 的话,当前玩家 ...
- Java实现 LeetCode 258 各位相加
258. 各位相加 给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数. 示例: 输入: 38 输出: 2 解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2. 由 ...
- Java实现 LeetCode 200 岛屿数量
200. 岛屿数量 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量.一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的.你可以假设网格的四个边均被水包围. ...
- Java实现LeetCode #986 - Interval List Intersections
class Solution { public: vector<Interval> intervalIntersection(vector<Interval>& A, ...
- Java实现 蓝桥杯 历届试题 约数倍数选卡片
问题描述 闲暇时,福尔摩斯和华生玩一个游戏: 在N张卡片上写有N个整数.两人轮流拿走一张卡片.要求下一个人拿的数字一定是前一个人拿的数字的约数或倍数.例如,某次福尔摩斯拿走的卡片上写着数字" ...
- Java实现第十届蓝桥杯外卖店优先级
试题 G: 外卖店优先级 时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分 [问题描述] "饱了么"外卖系统中维护着 N 家外卖店,编号 1 ∼ N.每家外卖店 ...
- java实现第四届蓝桥杯剪格子
剪格子 题目描述 如图p1.jpg所示,3 x 3 的格子中填写了一些整数. 我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是60. 本题的要求就是请你编程判定:对给定的m x n 的格子 ...
- TZOJ Start
描述 After the Online Round contest, we believe that you have already known how to write programs in A ...
- 关于virgo-tomcat-server-3.6.0.RELEASE服务的启动
1.先查看程序是否启动,如果已经启动可以执行第3步的操作进行关闭. [user01@ ~]$ # ps -ef|grep java //查看virgo-tomcat-server的java进程是否存在 ...
- k8s-ephemeral和init容器
截止到目前k8s1.18版本,k8s已经支持四种类型的container:标准容器,sidecar容器,init容器,ephemeral容器. 一:ephemeral容器 1.1.什么是ephemer ...