Python探索之静态方法和类方法的区别详解


Posted in Python onOctober 27, 2017

面相对象程序设计中,类方法和静态方法是经常用到的两个术语。
逻辑上讲:类方法是只能由类名调用;静态方法可以由类名或对象名进行调用。

python staticmethod and classmethod

Though classmethod and staticmethod are quite similar, there's a slight difference in usage for both entities: classmethod must have a reference to a class object as the first parameter, whereas staticmethod can have no parameters at all.
Let's look at all that was said in real examples.

尽管 classmethod 和 staticmethod 非常相似,但在用法上依然有一些明显的区别。classmethod 必须有一个指向 类对象 的引用作为第一个参数,而 staticmethod 可以没有任何参数。

让我们看几个例子。

例子 ? Boilerplate

Let's assume an example of a class, dealing with date information (this is what will be our boilerplate to cook on):

class Date(object):
 
  def __init__(self, day=0, month=0, year=0):
    self.day = day
    self.month = month
    self.year = year

This class obviously could be used to store information about certain dates (without timezone information; let's assume all dates are presented in UTC).

很明显,这个类的对象可以存储日期信息(不包括时区,假设他们都存储在 UTC)。

Here we have __init__, a typical initializer of Python class instances, which receives arguments as a typical instancemethod, having the first non-optional argument (self) that holds reference to a newly created instance.

这里的 init 方法用于初始化对象的属性,它的第一个参数一定是 self,用于指向已经创建好的对象。

Class Method

We have some tasks that can be nicely done using classmethods.
Let's assume that we want to create a lot of Date class instances having date information coming from outer source encoded as a string of next format (‘dd-mm-yyyy'). We have to do that in different places of our source code in project.

利用 classmethod 可以做一些很棒的东西。

比如我们可以支持从特定格式的日期字符串来创建对象,它的格式是 (‘dd-mm-yyyy')。很明显,我们只能在其他地方而不是 init 方法里实现这个功能。

So what we must do here is:
Parse a string to receive day, month and year as three integer variables or a 3-item tuple consisting of that variable.
Instantiate Date by passing those values to initialization call.
This will look like:

大概步骤:

解析字符串,得到整数 day, month, year。

使用得到的信息初始化对象

代码如下

day, month, year = map(int, string_date.split('-'))
date1 = Date(day, month, year)

理想的情况是 Date 类本身可以具备处理字符串时间的能力,解决了重用性问题,比如添加一个额外的方法。

For this purpose, C++ has such feature as overloading, but Python lacks that feature- so here's when classmethod applies. Lets create another “constructor”.

C++ 可以方便的使用重载来解决这个问题,但是 python 不具备类似的特性。 所以接下来我们要使用 classmethod 来帮我们实现。

@classmethod
 def from_string(cls, date_as_string):
 day, month, year = map(int, date_as_string.split('-'))
 date1 = cls(day, month, year)
 return date1
date2 = Date.from_string('11-09-2012')

Let's look more carefully at the above implementation, and review what advantages we have here:
We've implemented date string parsing in one place and it's reusable now.
Encapsulation works fine here (if you think that you could implement string parsing as a single function elsewhere, this solution fits OOP paradigm far better).
cls is an object that holds class itself, not an instance of the class. It's pretty cool because if we inherit our Date class, all children will have from_string defined also.

让我们在仔细的分析下上面的实现,看看它的好处。

我们在一个方法中实现了功能,因此它是可重用的。 这里的封装处理的不错(如果你发现还可以在代码的任意地方添加一个不属于 Date 的函数来实现类似的功能,那很显然上面的办法更符合 OOP 规范)。 cls 是一个保存了 class 的对象(所有的一切都是对象)。 更妙的是, Date 类的衍生类都会具有 from_string 这个有用的方法。

Static method
What about staticmethod? It's pretty similar to classmethod but doesn't take any obligatory parameters (like a class method or instance method does).
Let's look at the next use case.
We have a date string that we want to validate somehow. This task is also logically bound to Date class we've used so far, but still doesn't require instantiation of it.
Here is where staticmethod can be useful. Let's look at the next piece of code:

staticmethod 没有任何必选参数,而 classmethod 第一个参数永远是 cls, instancemethod 第一个参数永远是 self。

@staticmethod
def is_date_valid(date_as_string):
 day, month, year = map(int, date_as_string.split('-'))
 return day <= 31 and month <= 12 and year <= 3999
 
# usage:
is_date = Date.is_date_valid('11-09-2012')

So, as we can see from usage of staticmethod, we don't have any access to what the class is- it's basically just a function, called syntactically like a method, but without access to the object and it's internals (fields and another methods), while classmethod does.

所以,从静态方法的使用中可以看出,我们不会访问到 class 本身 ? 它基本上只是一个函数,在语法上就像一个方法一样,但是没有访问对象和它的内部(字段和其他方法),相反 classmethod 会访问 cls, instancemethod 会访问 self。

总结

以上就是本文关于Python探索之静态方法和类方法的区别详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:Python探索之爬取电商售卖信息代码示例、Python面向对象编程基础解析(一)等,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持。

Python 相关文章推荐
Python 搭建Web站点之Web服务器网关接口
Nov 06 Python
Python调用C++程序的方法详解
Jan 24 Python
Python 常用的安装Module方式汇总
May 06 Python
Centos7 Python3下安装scrapy的详细步骤
Mar 15 Python
Python使用Flask-SQLAlchemy连接数据库操作示例
Aug 31 Python
Python 等分切分数据及规则命名的实例代码
Aug 16 Python
Python中的单下划线和双下划线使用场景详解
Sep 09 Python
Python使用selenium + headless chrome获取网页内容的方法示例
Oct 16 Python
Python模块_PyLibTiff读取tif文件的实例
Jan 13 Python
基于K.image_data_format() == 'channels_first' 的理解
Jun 29 Python
python爬取网易云音乐热歌榜实例代码
Aug 07 Python
Python+Xlwings 删除Excel的行和列
Dec 19 Python
Python探索之爬取电商售卖信息代码示例
Oct 27 #Python
Python 列表理解及使用方法
Oct 27 #Python
Python算法之求n个节点不同二叉树个数
Oct 27 #Python
Python探索之自定义实现线程池
Oct 27 #Python
python音频处理用到的操作的示例代码
Oct 27 #Python
彻底理解Python list切片原理
Oct 27 #Python
Python在不同目录下导入模块的实现方法
Oct 27 #Python
You might like
封装一个PDO数据库操作类代码
2009/09/09 PHP
php上传excel表格并获取数据
2017/04/27 PHP
PHP实现APP微信支付的实例讲解
2018/02/10 PHP
php判断电子邮件是否正确方法
2018/12/04 PHP
PHP设计模式之观察者模式定义与用法分析
2019/04/04 PHP
EasyUi tabs的高度与宽度根据IE窗口的变化自适应代码
2010/10/26 Javascript
解析js中获得父窗口链接getParent方法以及各种打开窗口的方法
2013/06/19 Javascript
js导出table到excel同时兼容FF和IE示例
2013/09/03 Javascript
使用postMesssage()实现iframe跨域页面间的信息传递
2016/03/29 Javascript
JS实现的系统调色板完整实例
2016/12/21 Javascript
Bootstrap Table使用整理(四)之工具栏
2017/06/09 Javascript
JS实现验证码倒计时的注册页面
2018/01/02 Javascript
微信小程序异步API为Promise简化异步编程的操作方法
2018/08/14 Javascript
小程序中设置缓存过期的实现方法
2020/01/14 Javascript
js实现直播点击飘心效果
2020/08/19 Javascript
浅谈nuxtjs校验登录中间件和混入(mixin)
2020/11/06 Javascript
[48:53]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS VG第一场
2014/05/26 DOTA
python计算圆周长、面积、球体体积并画出圆
2014/04/08 Python
在Python中使用cookielib和urllib2配合PyQuery抓取网页信息
2015/04/25 Python
Python实现利用最大公约数求三个正整数的最小公倍数示例
2017/09/30 Python
Python内建模块struct实例详解
2018/02/02 Python
将python运行结果保存至本地文件中的示例讲解
2019/07/11 Python
Python 中 -m 的典型用法、原理解析与发展演变
2019/11/11 Python
Python return语句如何实现结果返回调用
2020/10/15 Python
python3代码中实现加法重载的实例
2020/12/03 Python
美国排名第一的泳池用品直接来源:In The Swim
2019/09/23 全球购物
办公室年终个人自我评价
2013/10/28 职场文书
体育专业个人求职信范文
2013/12/27 职场文书
党员公开承诺事项
2014/03/25 职场文书
小学优秀班集体申报材料
2014/05/25 职场文书
2016元旦文艺汇演主持词(开场白+结束语)
2015/12/03 职场文书
全国劳模先进事迹材料(2016精选版)
2016/02/25 职场文书
市语委办2016年第十九届“推普周”活动总结
2016/04/05 职场文书
图文详解nginx日志切割的实现
2022/01/18 Servers
python blinker 信号库
2022/05/04 Python
JS前端宏任务微任务及Event Loop使用详解
2022/07/23 Javascript