尽管classmethod和staticmethod非常的相似,但是两者在具体的使用上还是有着细微的差别:classmethod必须使用类对象作为第一个参数,而staticmethod则可以不传递任何参数。
通常情况下,在类中定义的所有函数(注意了,这里说的就是所有,跟self啥的没关系,self也只是一个再普通不过的参数而已)都是对象的绑定方法,对象在调用绑定方法时会自动将自己作为参数传递给方法的第一个参数。除此之外还有两种常见的方法:静态方法和类方法,二者是为类量身定制的,但是实例非要使用,也不会报错。
等价代码1
class Foo:
def spam(x,y,z): #类中的一个函数,千万不要懵逼,self和x啥的没有不同都是参数名
print(x,y,z)
spam=staticmethod(spam) #把spam函数做成静态方法
基于之前所学装饰器的知识,@staticmethod 等同于spam=staticmethod(spam),于是
等价代码1
class Foo:
@staticmethod #装饰器
def spam(x,y,z):
print(x,y,z)
In [56]: 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
...: @classmethod
...: def from_string(cls, date_as_string):#cls相当于Date
# day, month, year = map(int, string_date.split('-'))
# date1 = Date(day, month, year)
...: day, month, year = map(int, date_as_string.split('-'))
...: date1 = cls(day, month, year) #cls相当于Date
...: return date1
...: @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
In [57]: date2 = Date.from_string('11-09-2012') #类方法,()
In [58]: date2
Out[58]: <__main__.Date at 0x26973f86ac8>
In [60]: is_date = Date.is_date_valid('11-06-2012') #静态方法, ()
In [61]: is_date
Out[61]: True
classmethod
1.在一个地方解析日期字符串并且重复使用它。
2.做到很好的封装(相对于把执行字符串解析作为一个单独的函数在任何地方执行,这里使用的方法更符合OOP的范式)
3.cls表示类对象,而不是类实例。这样很酷,因为如果我们继承Date类,那么所有的子类也都将拥有from_string这个方法。
staticmethod
它和classmethod非常的相似,但是不强制要求传递参数(但是做的事与类方法或实例方法一样)。
不需要访问它所属的类,它本质上就是一个函数,调用方式和调用函数一样,不同的是它不关注对象和对象内部属性。