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 ...
随机推荐
- JavaScript(ES6之前)数组方法总结
一.数组的创建 1.使用 Array 构造函数 var arr1 = new Array(); // 创建一个空数组 var arr2 = new Array(20); // 创建一个包含20项的数组 ...
- centos6.5上安装git
亲测有效 https://blog.csdn.net/wxy540843763/article/details/80197301
- subline html5的快捷键
选择类 Ctrl+D 选中光标所占的文本,继续操作则会选中下一个相同的文本. Alt+F3 选中文本按下快捷键,即可一次性选择全部的相同文本进行同时编辑.举个栗子:快速选中并更改所有相同的变量名.函数 ...
- 使用Anaconda管理Python环境
修改镜像源 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ conda con ...
- 在 windows 上安装 git 2.15
下载 by win 下载地址:https://git-scm.com/download/win 如下图.选择对应的版本下载: 安装 by win 1.双击下载好的git安装包.弹出提示框.如下图: 2 ...
- shell 学习笔记 LinuxShell脚本攻略(第2版)
注释用#号:多条命令通过分号或回车来分隔 echo会自动换行,若不想换行,则加上-n参数,如 echo -n "nice to meet you" echo后面的内容可以不带引号, ...
- go if for while 的使用
fileName := "a.txt"contents ,err := ioutil.ReadFile(fileName) if err != nil{ fmt.Println(& ...
- 判断字符串是否是IP地址
#include <stdio.h>#include <string.h> bool isIP(const char* str); int main(){ char str[] ...
- appium问题汇总(持续更新。。。)
WEBVIEW_unknown adb版本较低,adb 1.0.32版本不支持安卓8.x版本,更新adb版本后正常 Install homebrew ruby -e "$(curl -fsS ...
- bootstrap-wysihtml5 ckeditor 修改富文本编辑器可以上传图片
bootstrap-wysihtml5 ckeditor 修改富文本编辑器可以上传图片 bootstrap-wysihtml5实际使用内核为ckeditor 故这里修改ckeditor即可 ...