Python class only method

Метод classmethod() и staticmethod в Python

Метод classmethod() возвращает метод класса для данной функции.

classmethod() считается не-Pythonic, поэтому в более новых версиях Python вы можете использовать декоратор @classmethod для определения метода класса.

@classmethod def func(cls, args. )

Метод classmethod() принимает единственный параметр:

И возвращает метод класса для данной функции.

Что такое метод класса?

Метод класса — это метод, который привязан к классу, а не к его объекту. Он не требует создания экземпляра класса, как staticmethod.

Разница между статическим методом и методом класса:

  • Статический метод ничего не знает о классе и имеет дело только с параметрами.
  • Метод класса работает с классом, поскольку его параметром всегда является сам класс.

Метод класса может вызываться как классом, так и его объектом.

Class.classmethod() Or even Class().classmethod()

Но несмотря ни на что, метод класса всегда присоединяется к классу с первым аргументом, поскольку класс cls .

Пример 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()

Здесь у нас есть класс Person с возрастом переменной, присвоенным 25. У нас также есть функция printAge, которая принимает единственный параметр cls, а не self, который мы обычно принимаем. cls принимает в качестве параметра класс Person, а не объект или экземпляр Person.

Теперь мы передаем метод Person.printAge в качестве аргумента методу класса функции. Это преобразует метод в метод класса, так что он принимает первый параметр как класс (т.е. Person).

В последней строке мы вызываем printAge без создания объекта Person, как мы это делаем для статических методов. Это печатает возраст переменной класса.

Когда вы использовать метод класса?

1 Фабричные методы

Фабричные методы — это те методы, которые возвращают объект класса (например, конструктор) для различных вариантов использования.

Читайте также:  Выберите верные утверждения php

Это похоже на перегрузку функций в 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 принимает класс, имя и год рождения, вычисляет текущий возраст, вычитая его из текущего года, и возвращает экземпляр класса.

Метод fromBirthYear принимает класс Person (а не объект Person) в качестве первого параметра cls и возвращает конструктор путем вызова cls (name, date.today(). Year — BirthYear), что эквивалентно Person (name, date.today() .year — Год рождения)

Перед методом мы видим @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))

Здесь использование статического метода для создания экземпляра класса требует от нас жесткого кодирования типа экземпляра во время создания.

fromFathersAge возвращает не объект Man, а объект его базового класса Person.

Это нарушает парадигму ООП. Использование метода класса от fromBirthYear может гарантировать ООП-кодирование кода, поскольку он принимает первый параметр как сам класс и вызывает его фабричный метод.

Встроенная функция staticmethod() возвращает статический метод для данной функции.

В более новых версиях Python вы можете использовать декоратор @staticmethod.

@staticmethod def func(args, . )

Метод staticmethod() принимает единственный параметр:

Читайте также:  Sublime text and php

Staticmethod() возвращает статический метод для функции, переданной в качестве параметра.

Что такое статический метод?

Статические методы, как и методы класса, — это методы, привязанные к классу, а не к его объекту. Они не требуют создания экземпляра класса. Они не зависят от состояния объекта.

Разница между статическим методом и методом класса:

  • Статический метод ничего не знает о классе и имеет дело только с параметрами.
  • Метод класса работает с классом, поскольку его параметром всегда является сам класс.

Их может вызывать как класс, так и его объект.

Class.staticmethodFunc() or even Class().staticmethodFunc()

Создание статического метода с помощью staticmethod()

class Mathematics: def addNumbers(x, y): return x + y # create addNumbers static method Mathematics.addNumbers = staticmethod(Mathematics.addNumbers) print('The sum is:', Mathematics.addNumbers(5, 10))

Когда использовать статические методы?

1. Группирование функции в класс

Статические методы имеют ограниченный вариант использования, потому что, как методы класса или любые другие методы внутри класса, они не могут получить доступ к свойствам самого класса.

Однако, когда вам нужна служебная функция, которая не имеет доступа к каким-либо свойствам класса, но имеет смысл, что она принадлежит этому классу, мы используем статические функции.

Создание служебной функции как статического метода

class Dates: def __init__(self, date): self.date = date def getDate(self): return self.date @staticmethod def toDashDate(date): return date.replace("/", "-") date = Dates("15-12-2016") dateFromDB = "15/12/2016" dateWithDash = Dates.toDashDate(dateFromDB) if(date.getDate() == dateWithDash): print("Equal") else: print("Unequal")

Здесь у нас есть класс Dates, который работает только с датами с тире. Однако в нашей предыдущей базе данных все даты были указаны в виде косой черты.

Чтобы преобразовать даты с косой чертой в даты с тире, мы создали служебную функцию toDashDate в Dates.

Это статический метод, потому что он не требует доступа к каким-либо свойствам самой даты, а требует только параметров.

Мы также можем создать toDashDate вне класса, но поскольку он работает только для дат, логично оставить его внутри класса Dates.

Наличие единой реализации

Статические методы используются, чтобы подклассы класса изменяли или переопределяли конкретную реализацию метода.

Как наследование работает со статическим методом?

class Dates: def __init__(self, date): self.date = date def getDate(self): return self.date @staticmethod def toDashDate(date): return date.replace("/", "-") class DatesWithSlashes(Dates): def getDate(self): return Dates.toDashDate(self.date) date = Dates("15-12-2016") dateFromDB = DatesWithSlashes("15/12/2016") if(date.getDate() == dateFromDB.getDate()): print("Equal") else: print("Unequal")

Здесь мы не хотели бы, чтобы подкласс DatesWithSlashes переопределял статический служебный метод toDashDate, потому что он используется только один раз, то есть меняет дату на тире-даты.

Читайте также:  Вставка части кода html

Мы могли бы легко использовать статический метод в наших интересах, переопределив метод getDate() в подклассе, чтобы он хорошо работал с классом DatesWithSlashes.

Источник

Drucken Clam’s Coding Blog

>>> foo = Foo()
>>> foo.bar_inst
>
>>> foo.bar_static

>>> foo.bar_class
>

foo.bar_static just returns a function object as if bar_static were defined outside of class. (In Python 2, it would return an unbound method; Python 3 has removed the concept of unbound methods. So a function is either a bound method or a regular function object)

How It Works — Descriptor

Every function object outside of or inside of class is a descriptor because it implements __get__ magic method.

>>> def bar(): . pass . >>> bar.__get__ '__get__' of function object at 0x025A3420>
>>> Foo.__dict__['bar_inst'].__get__(foo, type(foo)) object at 0x025A0EB0>>
>>> Foo.__dict__['bar_static'].__get__(foo, type(foo)) 0x025A34F8> >>> Foo.__dict__['bar_class'].__get__(foo, type(foo)) type.bar_class of class 'test.Foo'>>

My Implementation of Static Method

Utilizing descriptor and decorator, it’s very easy to implement static_method. We just ignore obj and objtype return self.f — the function object.

class MyStaticMethod: def __init__(self, f): self.f = f def __get__(self, obj, objtype=None): return self.f
class Foo: @staticmethod def bar_static(): print("This is bar_static") @MyStaticMethod def bar_my_static(): print("This is bar_my_static")

My Implementation of Class Method

class method needs to pass objtype to the function object as the first argument, so it might be implemented as follows:

class MyClassMethod: def __init__(self, f): self.f = f def __get__(self, obj, objtype=None): if objtype is None: objtype = type(obj) def classfunc(*args, **kwargs): self.f(objtype, *args, **kwargs) return classfunc
class Foo: def bar_inst(self): print(self, "This is bar_inst") @classmethod def bar_class(cls): print(cls, "This is bar_class") @MyClassMethod def bar_my_class(cls): print(cls, "This is bar_my_class")

Implementation of Class Only Method

class classonlymethod(classmethod): def __get__(self, instance, owner): if instance is not None: raise AttributeError("This method is available only on the class, not on instances.") return super(classonlymethod, self).__get__(instance, owner))

If a function is decorated by classonlymthod, call it from instance will raise an exception.

class Foo: @classonlymethod def bar_class_only(cls): print(cls, "This is bar_class_only")
  • Get link
  • Facebook
  • Twitter
  • Pinterest
  • Email
  • Other Apps

Источник

Оцените статью