什么是类方法?
类方法是绑定到类而不是对象的方法。它不需要创建类实例,就像staticmethod一样。
静态方法和类方法之间的区别是:
- 静态方法对类一无所知,只处理参数
- 类方法与类一起使用,因为其参数始终是类本身。
例子1
class Person:
age = 25
def printAge(cls):
print('The age is:', cls.age)
# create printAge class method
Person.printAge = classmethod(Person.printAge)
#
Person.printAge()
在这里,我们有一个类 Person,其变量age被指定为25。
我们还有一个函数printAge带有一个单独的参数cls,而不是平常我们见到的self。
cls接受类Person作为参数,而不是Person的对象/实例。
现在,我们将该方法Person.printAge作为参数传递给函数classmethod。这会将printAge转换为类方法,以便它接受第一个参数作为类(即Person)。
在最后一行中,调用printAge函数没有像静态方法那样创建Person对象。然后打印类变量age。
运行结果:
The age is: 25
例子2
from datetime import date
# random Person
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
#注意这里的@classmethod
@classmethod
def fromBirthYear(cls, name, birthYear):
return cls(name, date.today().year - birthYear)
def display(self):
print(self.name + "'s age is: " + str(self.age))
person = Person('Adam', 19)
person.display()
#这里可以通过实例person调用frombirthyear函数,这个函数返回name,age给Person类
person.fromBirthYear('yu',1997).display()
#这里不需要实例化,可以看成直接从Person类中调用frombirthyear函数。
person1 = Person.fromBirthYear('John', 1985)
person1.display()
输出结果
Adam's age is: 19
yu's age is: 23
John's age is: 31
__init__函数需要传入参数self,name和age。fromBirthYear函数需要传入cls,name,和birthYear
fromBirthYear函数将Person类(不是Person对象)作为第一个参数cls,并通过调用return构造函数cls(name, date.today().year - birthYear),这等效于Person(name, date.today().year - birthYear)
在该方法之前,我们看到了@classmethod。这称为装饰器,用于转换fromBirthYear为classmethod()的类方法。
decorator
decorator可以在原始函数中添加了一些新功能
def make_pretty(func):
def inner():
print("I got decorated")
func()
return inner
def ordinary():
print("I am ordinary")
ordinary()
pretty = make_pretty(ordinary)
#这里将ordinary函数传入make_pretty所需的参数中,添加ordinary()函数给inner()函数,然后再返回给pretty。
pretty()
输出如下
I am ordinary
I got decorated
I am ordinary
这种方法还可以这样表示
@make_pretty
def ordinary():
print("I am ordinary")
#函数头顶有个@,说明这个函数是要当成参数添加到make_pretty函数当中的。
#用@的方法和下面这种等价
def ordinary():
print("I am ordinary")
pretty = make_pretty(ordinary)