Метод classmethod () возвращает метод класса для данной функции.
Синтаксис classmethod()
метода:
classmethod (функция)
classmethod()
считается не-Pythonic, поэтому в новых версиях Python вы можете использовать @classmethod
декоратор для определения метода класса.
Синтаксис:
@classmethod def func (cls, args…)
classmethod () Параметры
classmethod()
метод принимает единственный параметр:
- function - Функция, которую нужно преобразовать в метод класса
Возвращаемое значение из classmethod ()
classmethod()
метод возвращает метод класса для данной функции.
Что такое метод класса?
Метод класса - это метод, который привязан к классу, а не к его объекту. Он не требует создания экземпляра класса, как staticmethod.
Разница между статическим методом и методом класса:
- Статический метод ничего не знает о классе и имеет дело только с параметрами.
- Метод класса работает с классом, поскольку его параметром всегда является сам класс.
Метод класса может вызываться как классом, так и его объектом.
Class.classmethod () Или даже 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()
Вывод
Возраст: 25
Здесь у нас есть класс Person
с возрастом переменной-члена, присвоенным 25.
У нас также есть функция, printAge
которая принимает единственный параметр cls, который self
мы обычно не принимаем.
cls принимает класс Person
как параметр, а не объект / экземпляр Person.
Теперь мы передаем метод Person.printAge
в качестве аргумента функции classmethod
. Это преобразует метод в метод класса, так что он принимает первый параметр как класс (т.е. Person).
В последней строке мы вызываем printAge
без создания объекта Person, как мы делаем для статических методов. Это печатает возраст переменной класса.
Когда вы используете метод класса?
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()
Вывод
Возраст Адама: 19 лет Джона: 31
Здесь у нас есть два создателя экземпляра класса, конструктор и fromBirthYear
метод.
Конструктор принимает обычные параметры name и age. В то время как fromBirthYear
принимает класс, имя и год рождения, вычисляет текущий возраст, вычитая его из текущего года, и возвращает экземпляр класса.
Метод 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))
Вывод
Верно Неверно
Здесь использование статического метода для создания экземпляра класса требует, чтобы мы жестко запрограммировали тип экземпляра во время создания.
Это явно вызывает проблемы при наследовании Person
в Man
.
fromFathersAge
Метод возвращает не Man
объект, а объект своего базового класса Person
.
Это нарушает парадигму ООП. Использование метода класса as fromBirthYear
может гарантировать ООП-ность кода, поскольку он принимает первый параметр как сам класс и вызывает его фабричный метод.