原文是stackoverflow
的一则高票回答,原文连接
可能以前也有人翻译过,可是恰好本身也有疑惑,因此搬运一下,我的水平有限因此可能翻译存在偏差,欢迎指正(如侵删)。python
尽管classmethod
和staticmethod
很是的类似,可是二者在具体的使用上仍是有着细微的差异:classmethod
必须使用类对象做为第一个参数,而staticmethod
则能够不传递任何参数。函数
让咱们经过实际的例子来看看。翻译
让咱们假设有处理日期信息的类:code
class Date(object): day = 0 month = 0 year = 0 def __init__(self, day=0, month=0, year=0): self.day = day self.month = month self.year = year
这个类很显然能够被用来存储某些日期信息(不考虑时区信息;让咱们假设全部的日期都用UTC
表示)对象
这里定义了__init__
,典型的类实例初始化方法,它做为典型的instancemethod
接受参数,其中第一个传递的必要参数是新建的实例自己。继承
有一些能够经过使用classmethod
很好解决的任务。字符串
假设咱们有不少('dd-mm-yyyy')
格式字符串的日期信息,想要把它们建立成Date
类实例。咱们不得不在项目的不一样地方作这些事情。get
因此咱们必需要作到:string
- 分析获得的年月日字符串,把它们转化成三个整形变量或者拥有三个元素的元组的变量。
- 经过传递这些值实例化
Date
。
获得:it
day, month, year = map(int, string_date.split('-')) date1 = Date(day, month, year)
C++拥有重载的特性能够达到这种目的,可是Python缺少此类特性。因此,python使用classmethod
的方式。让咱们尝试一种另类的构造函数。
@classmethod def from_string(cls, date_as_string): day, month, year = map(date_as_string.split('-')) date1 = cls(day, month, year) return date1 date2 = Date.from_string('11-09-2012')
进一步分析一下以上代码的执行,以及它的优点:
1.在一个地方解析日期字符串而且重复使用它。
2.作到很好的封装(相对于把执行字符串解析做为一个单独的函数在任何地方执行,这里使用的方法更符合OOP
的范式)
3.cls
表示类对象,而不是类实例。这样很酷,由于若是咱们继承Date
类,那么全部的子类也都将拥有from_string
这个方法。
那么staticmethod
又是什么呢?它和classmethod
很是的类似,可是不强制要求传递参数(可是作的事与类方法或实例方法同样)。
让咱们来看一个使用的例子。
咱们有一个日期字符串须要以某种方式验证。这个任务与以前同样要定义在Date
类内部,可是不要求实例化它。
静态方法在这种状况下就很是有用。看一下下面这个代码片断:
@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 is_date = Date.is_date_valid('11-09-2012')
如今正如咱们了解到的staticmethod
的使用,咱们不须要访问它所属的类,它本质上就是一个函数,调用方式和调用函数同样,不一样的是它不关注对象和对象内部属性。