python @classmethod
写在前面
写博客的时候,我发现拖延症很严重,本来昨天要开始写的,结果东看看,西翻翻,啥也没落实下来。时间过去了,口袋里的收获却寥寥无几。讨厌这样的自己。我要戒掉这个不好的毛病。
拖延症的底层原因之一是:不知如何下手
拖延症的底层原因之二是:每天都重复,疲了,累了
这里仅代表我自己
1..什么是classmethod
classmethod是用来指定一个类的方法为类方法
长的像下面这个样子
class cc:
@classmethod
def f(cls, arg1, arg2, ...): ...
cls通常用作类方法的第一参数 跟self有点类似( __init__里面的slef通常用作实例方法的第一参数)。即通常用self来传递当前类对象的实例,cls传递当前类对象。
self 和cls 没有特别的含义,作用只是把参数绑定到普通的函数上, 不一定非得是slef 或cls , 可以换成别的xxx
2..为什么会出现classmethod
(下面的比较琐碎,也不讲章法,但是这些点点滴滴我想记录下来,因为他们帮助我拼凑了这类知识的框架体系。我很喜欢用拼凑这个词,每次碰到一个完全陌生的鬼,总是这儿点点,那儿翻翻,每个足迹都会留下一点点碎片,慢慢的,逛的久了,再动手写写,基本上这一类内容在我脑子里渐渐形成个轮廓了,这个轮廓就是这些碎片拼凑出来的)
1--classmethod设计的目的是什么呢?事实上与Python面向对象编程有关的,由于Python不支持多个的參数重载构造函数,比方在C++里,构造函数能够依据參数个数不一样。能够写多个构造函数。Python为了解决问题,採用classmethod修饰符的方式,这样定义出来的函数就能够在类对象实例化之前调用这些函数,就相当于多个构造函数,解决多个构造函数的代码写在类外面的问题。
2---类最基本的作用是实例化出一个对象,但是有的时候再实例化之前,就需要先和类做一定的交互,这种交互可能会影响实际实例化的过程,所以必须放在调用构造函数之前。大概也可能是因为这个原因出现了classmethod
3---直接一点来说,我们知道对于一个普通的类,我们要使用其中的函数的话,需要对类进行实例化,而一个类中,某个函数前面加上了staticmethod或者classmethod的话,那么这个函数就可以不通过实例化直接调用,
可以通过类名进行调用的
4---@classmethod 定义的类方法是可选构造函数中,我们定义了一个类方法,类方法的第一个参数(cls)指代的就是类本身。类方法会用这个类来创建并返回最终的实例。使用类方法的另一个好处就是在继承的时候,保证了子类使用可选构造函数构造出来的类是子类的实例而不是父类的实例。
3..classmethod有什么用
在Java等语言中,这类功能通常通过工厂类(Factory)实现,先初始化一个工厂类的实例,然后由这个工厂类的实例构造实际需要的实例。在Python中,普通类完全可以替代Factory,而对于支持配置的Factory,就对应到相应的classmethod。
4..举第一个例子来理解classmethod
(因为我功力太浅,我真的没能理解@classmethod所起到的作用,但是知乎灵剑的这篇博客不明觉历,我还是先把这个例子这,说不定哪一天就想通了)
1)有一个插件系统,可以自动从插件目录中加载外部插件

2)Plugin是用户自定义插件的基类,它的构造函数接受一个api_interface的参数,把它保存到实例中。当想用这个接口的时候,调callback就好了,达到扩展功能的目的
3)事情不可能一成不变,要升级了,需要重新设计插件系统
4)插件数量变更多了,每个插件只干自己的事(比如,比如缝纫机插件只管缝衣服的事情,盖房子插件只管盖房子的事,警察插件只管抓坏人的事),那希望安装注册插件的时候希望插件声明好自己只干哪几样活(比如挖土插件要说好 :我只负责挖土,不负责缝衣服和盖房子)。
5)api_interface也变了,但是希望旧接口不做任何改变就能直接用
6)旧插件也不做任何改动就可以继续使用。
7)基于这样的需求,我们需要在构造plugin对象之前,就先从类中获取一定的信息。

5..再举个例子来理解classmethod的使用方法
这个是CSDN的dyh4201,链接都放下面了,这个通俗易懂,总感觉@classmethod还能发挥更大的用途,只是我还没完全参透,举不出例子来
看下面的定义的一个时间类: class Data_test(object):
day=0
month=0
year=0
def __init__(self,year=0,month=0,day=0):
self.day=day
self.month=month
self.year=year def out_date(self):
print "year :"
print self.year
print "month :"
print self.month
print "day :"
print self.day t=Data_test(2016,8,1)
t.out_date() 输出:
year :
2016
month :
8
day :
1 符合期望。 如果用户输入的是 "2016-8-1" 这样的字符格式,那么就需要调用Date_test 类前做一下处理: string_date='2016-8-1'
year,month,day=map(int,string_date.split('-'))
s=Data_test(year,month,day) 先把‘2016-8-1’ 分解成 year,month,day 三个变量,然后转成int,再调用Date_test(year,month,day)函数。 也很符合期望。 那我可不可以把这个字符串处理的函数放到 Date_test 类当中呢? 那么@classmethod 就开始出场了 class Data_test2(object):
day=0
month=0
year=0
def __init__(self,year=0,month=0,day=0):
self.day=day
self.month=month
self.year=year @classmethod
def get_date(cls,data_as_string):
#这里第一个参数是cls, 表示调用当前的类名
year,month,day=map(int,string_date.split('-'))
date1=cls(year,month,day)
#返回的是一个初始化后的类
return date1 def out_date(self):
print "year :"
print self.year
print "month :"
print self.month
print "day :"
print self.day 在Date_test类里面创建一个成员函数, 前面用了@classmethod装饰。 它的作用就是有点像静态类,比静态类不一样的就是它可以传进来一个当前类作为第一个参数。 那么如何调用呢? r=Data_test2.get_date("2016-8-6")
r.out_date()
输出:
year :
2016
month :
8
day :
1 这样子等于先调用get_date()对字符串进行出来,然后才使用Data_test的构造函数初始化。 这样的好处就是你以后重构类的时候不必要修改构造函数,只需要额外添加你要处理的函数,然后使用装饰符 @classmethod 就可以了。
6.在继承时也能工作的很好:
类方法的一个主要用途就是定义多个构造器。它接受一个class 作为第一个参数(cls)。在继承时也能工作的很好:

7..还有其他待挖掘
关于@classmethod,以后要是发现新的用途或者有更深的理解了,我再继续加到下面
参考
https://www.cnblogs.com/zfyouxi/p/5222811.html
http://30daydo.com/article/89
https://www.zhihu.com/question/20021164
https://blog.csdn.net/mr_hui_/article/details/82939979
https://www.cnblogs.com/agnewee/p/5653936.html
python @classmethod的更多相关文章
- python @classmethod 的使用场合
python @classmethod 的使用场合 官方的说法: classmethod(function)中文说明:classmethod是用来指定一个类的方法为类方法,没有此参数指定的类的方法为实 ...
- python @classmethod和@staticmethod区别
python 类方法和静态方法区别 python @classmethod和@staticmethod区别 Python中至少有三种比较常见的方法类型,即实例方法,类方法.静态方法.它们是如何定义的呢 ...
- Python classmethod 修饰符
描述 classmethod修饰符对应的函数不需要实例化,不需要self参数,但第一个参数需要是表示自身类的cls参数,可以调用类的属性,类的方法,实例化对象等. 语法 classmethod语法: ...
- python classmethod 和 staticmethod的区别
https://stackoverflow.com/questions/12179271/meaning-of-classmethod-and-staticmethod-for-beginner 1. ...
- python -- @classmethod @staticmethod区别和使用
python中的定义: class MyClass: ... @classmethod # classmethod的修饰符 def class_method(cls, arg1, arg2, ... ...
- Fluent Python: Classmethod vs Staticmethod
Fluent Python一书9.4节比较了 Classmethod 和 Staticmethod 两个装饰器的区别: 给出的结论是一个非常有用(Classmethod), 一个不太有用(Static ...
- python classmethod方法 和 staticmethod
classmethod() 是一个类方法,用来装饰对应的函数.被classmethod 装饰之后就无需实例化,也不需要在函数中传self,但是被装饰的函数第一个参数需要是cls来表示自身类.可以用来调 ...
- Python @classmethod和@staticmethod装饰器使用介绍
@classmethod和@staticmethod装饰器使用介绍 by:授客 QQ:1033553122 简介 静态方法:类中用 @staticmethod装饰的不带 self 参数的方法.类的静态 ...
- django classonlymethod 和 python classmethod的区别
--classmethod可以被一个实例调用,classonlyethod只能被类调用 class Kls(object): no_inst = 0 def __init__(self): Kls.n ...
随机推荐
- Python的range和xrange
range 函数说明:range([start,] stop[, step]),根据start与stop指定的范围以及step设定的步长,生成一个序列. range示例: >>> r ...
- P1005 矩阵取数游戏[区间dp]
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的\(m*n\)的矩阵,矩阵中的每个元素\(a_{i,j}\)均为非负整数.游戏规则如下: 每次取数时须从每行各取走一个元素,共n个.经过m次后 ...
- eclipse中JDK环境的搭建
现在就可以用记事本开发java程序了,但是eclipse是一款java开发不可缺少的IDE,并且安装简单,下面说一下步骤,首先下载eclipse, 官网下载链接:http://www.eclipse. ...
- Mac系统上,Firefox和Selenium不兼容的情况
解决办法,检查环境: Python 2.7.10 Firefox 46版本 Selenium 2.53.6 注意:将Firefox自动更新关闭,否则可能会出现自动升级以后无法执行Selenium用例的 ...
- vscode 输出面板字符编码问题
默认的输出中文会显示成乱码,需要在vscode内部的终端中输入 chcp 65001 缺点是需要每次打开vscode进行激活,另一种方式是在vscode的首选项中进行配置: "termina ...
- STM32的指令周期
在keil中编程时,写了一行代码,然后就想知道,执行这句C代码需要多长时间. 时钟周期在这就不解释了,频率的倒数. 指令周期,个人理解就是cpu执行一条汇编指令所需要的时间. 我们知道cm3使用的三级 ...
- 在mysql中用int类型存储IP
SELECT INET_ATON( '127.0.0.1' ); SELECT INET_NTOA();
- msf爆破
SSH服务口令猜解: msf > use auxiliary/scanner/ssh/ssh_loginmsf auxiliary(ssh_login) > show optionsmsf ...
- 解决vue多个路由共用一个页面的问题
在日常的vue开发中我们可能会遇见多个路由需要共用一个页面的需求,特别是当路由是通过动态添加的,不同的路由展示的东西只是数据不同其他没有变化.例如: ? 1 2 3 4 5 6 7 8 9 10 11 ...
- [报错解决] "MySQL server has gone away" 解决思路
大概的4个思路 1.超时,超时的阀值有wait_timeout这个参数控制 2.连接被人为的kill 3.发送的SQL语句过大超过max_allowed_packet的大小. (操作的sql语句太长了 ...