📅  最后修改于: 2020-09-20 03:54:23             🧑  作者: Mango
classmethod()
方法的语法为:
classmethod(function)
classmethod()
被认为是非Python语言的,因此在较新的Python版本中,可以使用@classmethod
装饰器进行classmethod定义。
语法为:
@classmethod
def func(cls, args...)
classmethod()
方法采用一个参数:
classmethod()
方法返回给定函数的类方法。
类方法是绑定到类而不是对象的方法。它不需要像静态方法一样创建类实例。
静态方法和类方法之间的区别是:
类方法可以同时由类及其对象调用。
Class.classmethod()
Or even
Class().classmethod()
但是无论如何,class方法总是以第一个参数作为类本身cls
附加到类上。
def classMethod(cls, args...)
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
。
工厂方法是那些针对不同用例返回类对象(如构造函数)的方法。
它类似于C++中的函数重载。由于Python没有这样的功能,因此使用了类方法和静态方法。
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)
等效Person(name, date.today().year - birthYear)
在该方法之前,我们看到@classmethod
。这称为装饰器,用于将fromBirthYear
转换为classmethod()
的类方法。
每当将工厂方法实现为类方法来派生一个类时,它都会确保正确创建派生类的实例。
您可以为上面的示例创建一个静态方法,但是它创建的对象将始终被硬编码为Base类。
但是,当您使用类方法时,它将创建派生类的正确实例。
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
的对象。
这违反了OOP范式。使用fromBirthYear
的类方法可以确保代码的面向对象,因为它将第一个参数作为类本身并调用其工厂方法。