classmethod()
方法返回给定函数的类方法。
示例
class Student:
marks = 0
def compute_marks(cls, obtained_marks):
cls.marks = obtained_marks
print('Obtained Marks:', cls.marks)
# convert compute_marks() to class method
Student.print_marks = classmethod(Student.compute_marks)
Student.print_marks(88)
# Output: Obtained Marks: 88
classmethod() 语法
classmethod()
方法的语法是
classmethod(function)
classmethod()
被认为是“不符合 Python 风格的”,因此在较新的 Python 版本中,你可以使用 @classmethod
装饰器 来定义类方法。
语法是
@classmethod def func(cls, args...)
classmethod() 参数
classmethod()
方法接受一个参数
- function - 需要转换为类方法的函数
classmethod() 返回值
classmethod()
方法返回给定函数的类方法。
什么是类方法?
类方法是绑定到类而不是其对象的方法。它不需要创建类实例,很像静态方法。
静态方法和类方法之间的区别是
- 静态方法对类一无所知,只处理参数
- 类方法与类一起工作,因为它的参数始终是类本身。
类方法可以由类及其对象调用。
Class.classmethod() Or even Class().classmethod()
但无论如何,类方法总是附属于一个类,其第一个参数是类本身 cls。
def classMethod(cls, args...)
示例 1:使用 classmethod() 创建类方法
class Person:
age = 25
def printAge(cls):
print('The age is:', cls.age)
# create printAge class method
Person.printAge = classmethod(Person.printAge)
Person.printAge()
输出
The age is: 25
这里,我们有一个类 Person
,其中一个成员变量 age 赋值为 25。
我们还有一个函数 printAge
,它接受一个参数 cls,而不是我们通常使用的 self
。
cls 接受类 Person
作为参数,而不是 Person 的对象/实例。
现在,我们将方法 Person.printAge
作为参数传递给函数 classmethod
。这会将方法转换为类方法,以便它接受第一个参数作为类(即 Person)。
在最后一行中,我们调用 printAge
而不创建 Person 对象,就像我们对静态方法所做的那样。这会打印类变量 age。
你何时使用类方法?
1. 工厂方法
工厂方法是那些针对不同用例返回类对象(如构造函数)的方法。
它类似于 C++ 中的函数重载。由于 Python 没有这样的功能,所以使用类方法和静态方法。
示例 2:使用类方法创建工厂方法
from datetime import date
# random Person
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
@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()
person1 = Person.fromBirthYear('John', 1985)
person1.display()
输出
Adam's age is: 19 John's age is: 31
这里,我们有两个类实例创建器,一个构造函数和一个 fromBirthYear
方法。
构造函数接受普通参数 name 和 age。而 fromBirthYear
接受 class、name 和 birthYear,通过从当前年份中减去出生年份来计算当前年龄并返回类实例。
fromBirthYear 方法将 Person 类(而不是 Person 对象)作为第一个参数 cls,并通过调用 cls(name, date.today().year - birthYear)
返回构造函数,这等效于 Person(name, date.today().year - birthYear)
在该方法之前,我们看到 @classmethod
。这称为将 fromBirthYear
转换为类方法(如 classmethod()
)的装饰器。
2. 继承中正确的实例创建
每当您从实现工厂方法作为类方法的类派生时,它都会确保派生类的正确实例创建。
您可以为上述示例创建一个静态方法,但它创建的对象将始终被硬编码为基类。
但是,当您使用类方法时,它会创建派生类的正确实例。
示例 3:类方法如何用于继承?
from datetime import date
# random Person
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
@staticmethod
def fromFathersAge(name, fatherAge, fatherPersonAgeDiff):
return Person(name, date.today().year - fatherAge + fatherPersonAgeDiff)
@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))
class Man(Person):
sex = 'Male'
man = Man.fromBirthYear('John', 1985)
print(isinstance(man, Man))
man1 = Man.fromFathersAge('John', 1965, 20)
print(isinstance(man1, Man))
输出
True False
在这里,使用静态方法创建类实例要求我们在创建时硬编码实例类型。
这在将 Person
继承到 Man
时显然会导致问题。
fromFathersAge
方法不返回 Man
对象,而是其基类 Person
的对象。
这违反了面向对象编程范式。使用类方法(如 fromBirthYear
)可以确保代码的面向对象性,因为它将第一个参数作为类本身并调用其工厂方法。
另请阅读