Когда следует использовать метод @classmethod и метод def (self)?

Интегрируя приложение Django, которое я раньше не использовал, я нашел два разных способа определения функций в классах. Автор, кажется, использует их оба очень преднамеренно. Первый – тот, который я сам использую много:

class Dummy(object): def some_function(self,*args,**kwargs): do something here self is the class instance 

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

 class Dummy(object): @classmethod def some_function(cls,*args,**kwargs): do something here cls refers to what? 

В документах Python classmethod декоратор объясняется следующим предложением:

Метод класса получает класс как неявный первый аргумент, как метод экземпляра получает экземпляр.

Поэтому я думаю, что cls относится к самой Dummy ( class , а не экземпляр). Я не совсем понимаю, почему это существует, потому что я всегда могу это сделать:

 type(self).do_something_with_the_class 

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

2 Solutions collect form web for “Когда следует использовать метод @classmethod и метод def (self)?”

Ваша догадка правильная – вы понимаете, как работает classmethod .

Почему эти методы могут быть вызваны как экземпляром OR в классе (в обоих случаях объект класса будет передан как первый аргумент):

 class Dummy(object): @classmethod def some_function(cls,*args,**kwargs): print cls #both of these will have exactly the same effect Dummy.some_function() Dummy().some_function() 

Об использовании этих экземпляров : Существует как минимум два основных способа использования метода class в экземпляре:

  1. self.some_function() вызовет версию some_function для фактического типа self , а не класса, в котором этот вызов появляется (и не будет нуждаться в внимании, если класс будет переименован); а также
  2. В случаях, когда some_function необходим для реализации некоторого протокола, но полезно вызвать только объект класса.

Разница с staticmethod : Существует еще один способ определения методов, которые не имеют доступа к данным экземпляра, называемым staticmethod . Это создает метод, который вообще не получает неявный первый аргумент; соответственно, он не будет передан никакой информации о экземпляре или классе, на котором он был вызван.

 In [6]: class Foo(object): some_static = staticmethod(lambda x: x+1) In [7]: Foo.some_static(1) Out[7]: 2 In [8]: Foo().some_static(1) Out[8]: 2 In [9]: class Bar(Foo): some_static = staticmethod(lambda x: x*2) In [10]: Bar.some_static(1) Out[10]: 2 In [11]: Bar().some_static(1) Out[11]: 2 

Основное использование, которое я нашел для него, – это адаптировать существующую функцию (которая не ожидает получения self ) как метод для класса (или объекта).

Если вы добавите декоратор @classmethod, значит, вы собираетесь сделать этот метод статическим методом java или C ++. (статический метод – общий термин, я думаю 😉 ) Python также имеет @staticmethod. и разница между classmethod и staticmethod заключается в том, можете ли вы получить доступ к классу или статической переменной с помощью аргумента или самого имени класса.

 class TestMethod(object): cls_var = 1 @classmethod def class_method(cls): cls.cls_var += 1 print cls.cls_var @staticmethod def static_method(): TestMethod.cls_var += 1 print TestMethod.cls_var #call each method from class itself. TestMethod.class_method() TestMethod.static_method() #construct instances testMethodInst1 = TestMethod() testMethodInst2 = TestMethod() #call each method from instances testMethodInst1.class_method() testMethodInst2.static_method() 

все эти классы увеличивают cls.cls_var на 1 и печатают его.

И все классы, использующие одно и то же имя в той же области или экземплярах, созданных с помощью этого класса, собираются поделиться этими методами. Существует только один TestMethod.cls_var, а также есть только один TestMethod.class_method (), TestMethod.static_method ()

И важный вопрос. почему этот метод необходим.

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

 
Interesting Posts for Van-Lav

как умножить несколько столбцов на столбе в Pandas

Как узнать кодировку файла в Python?

Одна и та же задача выполняется несколько раз

Добавление процесса в список (но ничего не делает с ним) изменяет поведение программы

Как обрезать в большую внутреннюю ограничительную рамку в OpenCV?

Плохая автоматическая триангуляция с Mayavi для окраски поверхности, известной только ее углом

Как python находит файл модуля, если оператор import содержит только имя файла?

Реализация алгоритма сжатия LZ78 в python

несколько объектов Json в одном файле извлечения python

SyntaxError с VirtualEnv + mod-wsgi в Django

Как изменить размер изображения с помощью PIL и сохранить его соотношение сторон?

Правильный способ аутентификации пользователей с угловыми и колбой

Нужна помощь с скриптом python (pandas)

Неправильная дата, связанная с ранним утром, соскоблила с веб-сайта погоды (Python) + только данные за январь?

Чтение ввода от перенаправленного stdin с помощью python

Python - лучший язык программирования в мире.