==
проверяет ссылки на объекты, .equals()
проверяет строковые значения.
Иногда кажется, что ==
сравнивает значения, потому что Java делает некоторые закулисные вещи, чтобы убедиться, что одинаковые строки в строке являются одним и тем же объектом.
Для Например:
String fooString1 = new String("foo");
String fooString2 = new String("foo");
// Evaluates to false
fooString1 == fooString2;
// Evaluates to true
fooString1.equals(fooString2);
// Evaluates to true, because Java uses the same object
"bar" == "bar";
Но будьте осторожны с нулями!
==
обрабатывает строки null
в порядке, но вызов .equals()
из пустой строки приведет к исключению:
String nullString1 = null;
String nullString2 = null;
// Evaluates to true
System.out.print(nullString1 == nullString2);
// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));
Итак, если вы знаете, что fooString1
может но не менее очевидно, что он проверяет значение null (из Java 7):
System.out.print(Objects.equals(fooString1, "bar"));
Может быть, немного пример кода поможет: Обратите внимание на разницу в сигнатурах вызова foo
, class_foo
и static_foo
:
class A(object):
def foo(self,x):
print "executing foo(%s,%s)"%(self,x)
@classmethod
def class_foo(cls,x):
print "executing class_foo(%s,%s)"%(cls,x)
@staticmethod
def static_foo(x):
print "executing static_foo(%s)"%x
a=A()
Ниже приведен обычный способ экземпляра объекта вызывает метод. Экземпляр объекта a
неявно передается как первый аргумент.
a.foo(1)
# executing foo(<__main__.A object at 0xb7dbef0c>,1)
С помощью методов класса класс экземпляра объекта неявно передается как первый аргумент вместо self
.
a.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)
Вы также можете вызвать class_foo
с помощью класса. Фактически, если вы определите что-то как метод класса, это, вероятно, потому, что вы намереваетесь называть его из класса, а не из экземпляра класса. A.foo(1)
поставил бы TypeError, но A.class_foo(1)
работает просто отлично:
A.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)
. Одно из используемых людьми методов класса - это создание наследуемых альтернативных конструкторов .
С помощью staticmethods ни один self
(экземпляр объекта), ни cls
(класс) неявно передаются в качестве первого аргумента. Они ведут себя как простые функции, за исключением того, что вы можете вызвать их из экземпляра или класса:
a.static_foo(1)
# executing static_foo(1)
A.static_foo('hi')
# executing static_foo(hi)
Статические методы используются для группировки функций, которые имеют некоторое логическое соединение с классом класса.
foo
- это просто функция, но когда вы вызываете a.foo
, вы не просто получаете функцию, вы получаете «частично примененную» версию функции с экземпляром объекта a
, связанным как первый аргумент функции. foo
ожидает 2 аргумента, а a.foo
ожидает только 1 аргумент.
a
привязан к foo
. Это означает термин «связанный» ниже:
print(a.foo)
# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>
С a.class_foo
, a
не привязан к class_foo
, а класс A
привязан к class_foo
].
print(a.class_foo)
# <bound method type.class_foo of <class '__main__.A'>>
Здесь, с помощью метода static, хотя это метод, a.static_foo
просто возвращает хорошую функцию ole без привязки аргументов. static_foo
ожидает 1 аргумент, а a.static_foo
ожидает также 1 аргумент.
print(a.static_foo)
# <function static_foo at 0xb7d479cc>
И, конечно же, то же самое происходит, когда вы вызываете static_foo
с классом A
.
print(A.static_foo)
# <function static_foo at 0xb7d479cc>
В чем разница между @staticmethod и @classmethod в Python?
blockquote>Возможно, вы видели код Python, такой как этот псевдокод, который демонстрирует подписи различных типов методов и дает объяснение каждому из них:
class Foo(object): def a_normal_instance_method(self, arg_1, kwarg_2=None): ''' Return a value that is a function of the instance with its attributes, and other arguments such as arg_1 and kwarg2 ''' @staticmethod def a_static_method(arg_0): ''' Return a value that is a function of arg_0. It does not know the instance or class it is called from. ''' @classmethod def a_class_method(cls, arg1): ''' Return a value that is a function of the class and other arguments. respects subclassing, it is called with the class it is called from. '''
Метод Normal Instance
Сначала я объясню
a_normal_instance_method
. Это точно называется «методом экземпляра». Когда используется метод экземпляра, он используется как частичная функция (в отличие от общей функции, определенной для всех значений при просмотре в исходном коде), которая при использовании первая из аргументов предопределена как экземпляр объект со всеми его атрибутами. Он имеет экземпляр связанного с ним объекта и должен вызываться из экземпляра объекта. Как правило, он будет обращаться к различным атрибутам экземпляра.Например, это экземпляр строки:
', '
, если мы используем метод экземпляра,
join
on эта строка, чтобы присоединиться к другой итерабельной, она, очевидно, является функцией экземпляра, в дополнение к функции итерируемого списка,['a', 'b', 'c']
:>>> ', '.join(['a', 'b', 'c']) 'a, b, c'
Связанные методы
Методы экземпляров могут быть связаны через пунктирный поиск для использования позже.
Например, это связывает метод
str.join
с экземпляром':'
:>>> join_with_colons = ':'.join
И позже мы можем использовать это как функцию, которая уже имеет первый связанный с ней аргумент. Таким образом, он работает как частичная функция экземпляра:
>>> join_with_colons('abcde') 'a:b:c:d:e' >>> join_with_colons(['FF', 'FF', 'FF', 'FF', 'FF', 'FF']) 'FF:FF:FF:FF:FF:FF'
Статический метод
Статический метод делает не аргумент.
Он очень похож на функцию уровня модуля.
Однако функция модуля должна находиться в модуле и быть специально импортирована в другие места, где она используется.
Если он привязан к объекту, он также будет удобно перемещаться по объекту посредством импорта и наследования.
Примером статического метода является
str.maketrans
, перемещенный из модульstring
в Python 3. Он делает таблицу перевода подходящей для потребленияstr.translate
. Это кажется довольно глупым при использовании из экземпляра строки, как показано ниже, но импорт функции из модуляstring
довольно неуклюжий, и приятно иметь возможность вызвать его из класса, как вstr.maketrans
# demonstrate same function whether called from instance or not: >>> ', '.maketrans('ABC', 'abc') {65: 97, 66: 98, 67: 99} >>> str.maketrans('ABC', 'abc') {65: 97, 66: 98, 67: 99}
В python 2 вам нужно импортировать эту функцию из все более менее полезного строкового модуля:
>>> import string >>> 'ABCDEFG'.translate(string.maketrans('ABC', 'abc')) 'abcDEFG'
Метод класса
Метод класса аналогичен методу экземпляра, поскольку он принимает неявный первый аргумент, но вместо того, чтобы принимать экземпляр, он принимает класс. Часто они используются как альтернативные конструкторы для лучшего семантического использования, и они будут поддерживать наследование.
Самым каноническим примером встроенного метода класса является
dict.fromkeys
.>>> dict.fromkeys(['a', 'b', 'c']) {'c': None, 'b': None, 'a': None}
Когда мы подклассифицируем dict, мы можем использовать тот же самый метод, который был бы использован в качестве альтернативного конструктора dict. конструктор, который создает экземпляр подкласса.
>>> class MyDict(dict): 'A dict subclass, use to demo classmethods' >>> md = MyDict.fromkeys(['a', 'b', 'c']) >>> md {'a': None, 'c': None, 'b': None} >>> type(md) <class '__main__.MyDict'>
См. исходный код pandas для других подобных примеров альтернативных конструкторов, а также официальную документацию Python на
classmethod
иstaticmethod
.
Другое соображение относительно метода staticmethod vs classmethod связано с наследованием. Скажем, у вас есть следующий класс:
class Foo(object):
@staticmethod
def bar():
return "In Foo"
И тогда вы хотите переопределить bar()
в дочернем классе:
class Foo2(Foo):
@staticmethod
def bar():
return "In Foo2"
Это работает, но обратите внимание, что теперь bar()
в дочернем классе (Foo2
) больше не может использовать что-либо конкретное для этого класса. Например, скажем, Foo2
имеет метод, названный magic()
, который вы хотите использовать в реализации Foo2
bar()
:
class Foo2(Foo):
@staticmethod
def bar():
return "In Foo2"
@staticmethod
def magic():
return "Something useful you'd like to use in bar, but now can't"
Обходной путь здесь - вызвать Foo2.magic()
в bar()
, но затем вы повторяетесь (если имя Foo2
изменяется, вам нужно будет запомнить этот метод bar()
).
Для меня это небольшое нарушение принципа open / closed , так как решение, принятое в Foo
, влияет на вашу способность реорганизовать общий код в производном классе (т.е. он менее открыт для расширения). Если bar()
были classmethod
, мы были бы в порядке:
class Foo(object):
@classmethod
def bar(cls):
return "In Foo"
class Foo2(Foo):
@classmethod
def bar(cls):
return "In Foo2 " + cls.magic()
@classmethod
def magic(cls):
return "MAGIC"
print Foo2().bar()
Дает: In Foo2 MAGIC
@staticmethod
просто отключает функцию по умолчанию как дескриптор метода. classmethod переносит вашу функцию в контейнер, вызываемый, который передает ссылку на собственный класс в качестве первого аргумента:
>>> class C(object):
... pass
...
>>> def f():
... pass
...
>>> staticmethod(f).__get__(None, C)
<function f at 0x5c1cf0>
>>> classmethod(f).__get__(None, C)
<bound method type.f of <class '__main__.C'>>
На самом деле, classmethod
имеет служебные данные во время выполнения, но дает возможность получить доступ к владеющий классом. В качестве альтернативы я рекомендую использовать метакласс и помещать методы класса в этот метакласс:
>>> class CMeta(type):
... def foo(cls):
... print cls
...
>>> class C(object):
... __metaclass__ = CMeta
...
>>> C.foo()
<class '__main__.C'>
c = C(); c.foo()
вызывает AttributeError, вам нужно будет сделать type(c).foo()
. Это также можно считать особенностью - я не могу придумать, почему вы хотите этого.
– Aaron Hall♦
14 June 2016 в 21:57
Статический метод - это метод, который ничего не знает о классе или экземпляре, на который он был вызван. Он просто получает аргументы, которые были переданы, не подразумевается первый аргумент. Это в основном бесполезно в Python - вы можете просто использовать функцию модуля вместо staticmethod.
С другой стороны, метод класса - это метод, который получает переданный класс, на который он был вызван, или класс экземпляра, на который он был вызван, в качестве первого аргумента. Это полезно, если вы хотите, чтобы этот метод был фабрикой для класса: поскольку он получает фактический класс, который он вызывал в качестве первого аргумента, вы всегда можете создать экземпляр правильного класса, даже если задействованы подклассы. Обратите внимание, например, как dict.fromkeys()
, classmethod, возвращает экземпляр подкласса при вызове в подклассе:
>>> class DictSubclass(dict):
... def __repr__(self):
... return "DictSubclass"
...
>>> dict.fromkeys("abc")
{'a': None, 'c': None, 'b': None}
>>> DictSubclass.fromkeys("abc")
DictSubclass
>>>
метод класса vs статический метод в Python
Метод класса
Декоратор @classmethod - встроенный декоратор функций, который является выражением, которое оценивается после определения вашей функции. Результат этой оценки затеняет ваше определение функции.
Метод класса получает класс как неявный первый аргумент, так же как метод экземпляра получает экземпляр
Синтаксис:
class C(object):
@classmethod
def fun(cls, arg1, arg2, ...):
....
fun: function that needs to be converted into a class method
returns: a class method for function.
Статический метод
Статический метод не получает неявный первый аргумент.
Синтаксис:
class C(object):
@staticmethod
def fun(arg1, arg2, ...):
...
returns: a static method for function fun.
Метод класса vs Статический метод
Когда использовать что?
Как определить метод класса и статический метод?
Чтобы определить метод класса в python, мы используем декоратор @classmethod и определяем статический метод, которым мы используем декоратор @staticmethod.
Давайте посмотрим на пример чтобы понять разницу между ними. Скажем, мы хотим создать класс Person. Теперь python не поддерживает перегрузку метода, например, C ++ или Java, поэтому мы используем методы класса для создания заводских методов. В приведенном ниже примере мы используем метод класса для создания объекта person из года рождения.
Как объяснялось выше, мы используем статические методы для создания служебных функций. В приведенном ниже примере мы используем статический метод для проверки того, является ли человек взрослым или нет.
Реализация
# Python program to demonstrate
# use of class method and static method.
from datetime import date
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# a class method to create a Person object by birth year.
@classmethod
def fromBirthYear(cls, name, year):
return cls(name, date.today().year - year)
# a static method to check if a Person is adult or not.
@staticmethod
def isAdult(age):
return age > 18
person1 = Person('mayank', 21)
person2 = Person.fromBirthYear('mayank', 1996)
print person1.age
print person2.age
# print the result
print Person.isAdult(22)
Выход
21
21
True
Я начал изучать язык программирования с помощью C ++, а затем с Java, а затем с Python, и поэтому этот вопрос слишком беспокоил меня, пока я не понял простое использование каждого из них.
Метод класса: Python в отличие от Java и C ++ не имеет перегрузки конструктора. Итак, чтобы достичь этого, вы можете использовать classmethod
. следующий пример объяснит это
. Рассмотрим, что у нас есть класс Person
, который принимает два аргумента first_name
и last_name
и создает экземпляр Person.
class Person(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
Теперь, если требование возникает, когда вам нужно создать класс, используя только одно имя, просто first_name
. вы не можете сделать что-то подобное в python.
Это приведет к ошибке при попытке создать объект (экземпляр).
class Person(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
def __init__(self, first_name):
self.first_name = first_name
Однако вы можете добиться того же, используя @classmethod
, как указано ниже
class Person(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
@classmethod
def get_person(cls, first_name):
return cls(first_name, "")
Статический метод :: Это довольно просто, он не связан с экземпляром или классом, и вы можете просто вызвать это, используя имя класса.
Итак, скажем, в приведенном выше примере вам нужна проверка того, что first_name
не должно превышать 20 символов, вы можете просто сделать это.
@staticmethod
def validate_name(name):
return len(name) <= 20
, и вы можете просто вызвать с помощью Class Name
Person.validate_name("Gaurang Shah")
Чтобы решить, следует ли использовать @staticmethod или @classmethod , вы должны заглянуть внутрь своего метода. Если ваш метод обращается к другим переменным / методам в вашем классе, используйте @classmethod. С другой стороны, если ваш метод не касается каких-либо других частей класса, используйте @staticmethod.
class Apple:
_counter = 0
@staticmethod
def about_apple():
print('Apple is good for you.')
# note you can still access other member of the class
# but you have to use the class instance
# which is not very nice, because you have repeat yourself
#
# For example:
# @staticmethod
# print('Number of apples have been juiced: %s' % Apple._counter)
#
# @classmethod
# print('Number of apples have been juiced: %s' % cls._counter)
#
# @classmethod is especially useful when you move your function to other class,
# you don't have to rename the class reference
@classmethod
def make_apple_juice(cls, number_of_apples):
print('Make juice:')
for i in range(number_of_apples):
cls._juice_this(i)
@classmethod
def _juice_this(cls, apple):
print('Juicing %d...' % apple)
cls._counter += 1
В Python класс метод получает класс как неявный первый аргумент. Класс экземпляра объекта неявно передается как первый аргумент. Это может быть полезно, когда вы хотите, чтобы этот метод являлся фабрикой класса, поскольку он получает фактический класс (который называется методом) в качестве первого аргумента, можно создать экземпляр правого класса, даже если это также относится к подклассам.
Статический метод - это просто функция, определенная внутри класса. Он ничего не знает о классе или экземпляре, на который он был вызван, и получает только аргументы, которые были переданы без какого-либо неявного первого аргумента. Пример:
class Test(object):
def foo(self, a):
print "testing (%s,%s)"%(self,a)
@classmethod
def foo_classmethod(cls, a):
print "testing foo_classmethod(%s,%s)"%(cls,a)
@staticmethod
def foo_staticmethod(a):
print "testing foo_staticmethod(%s)"%a
test = Test()
staticmethods используются для группировки функций, которые имеют некоторое логическое соединение с классом в классе.
Анализировать метод @static, буквально предоставляя разные идеи.
Обычный метод класса - это неявный динамический метод, который принимает экземпляр как первый аргумент. Наоборот, статический метод не принимает экземпляр в качестве первого аргумента, поэтому он называется «статическим».
Статический метод действительно является такой нормальной функцией, как те, которые находятся вне определения класса. Он, к счастью, сгруппирован в класс только для того, чтобы стоять ближе, где он применяется, или вы можете прокручивать его, чтобы найти его.
@decorators были добавлены в python 2.4 Если вы используете python & lt; 2.4 вы можете использовать функцию classmethod () и staticmethod ().
Например, если вы хотите создать фабричный метод (функция, возвращающая экземпляр другой реализации класса в зависимости от того, какой аргумент он get) вы можете сделать что-то вроде:
class Cluster(object):
def _is_cluster_for(cls, name):
"""
see if this class is the cluster with this name
this is a classmethod
"""
return cls.__name__ == name
_is_cluster_for = classmethod(_is_cluster_for)
#static method
def getCluster(name):
"""
static factory method, should be in Cluster class
returns a cluster object for the given name
"""
for cls in Cluster.__subclasses__():
if cls._is_cluster_for(name):
return cls()
getCluster = staticmethod(getCluster)
Также обратите внимание, что это хороший пример использования метода класса и статического метода. Статический метод явно принадлежит классу, поскольку он использует класс Cluster внутренне. Классному классу нужна только информация об этом классе, а не экземпляр объекта.
Еще одно преимущество создания метода _is_cluster_for
classmethod заключается в том, что подкласс может решить изменить его реализацию, возможно, потому, что он довольно generic и может обрабатывать более одного типа кластера, поэтому просто проверить имя класса будет недостаточно.
Статические методы:
Преимущества статических методов:
@staticmethod
def some_static_method(*args, **kwds):
pass
Методы класса:
@classmethod
def some_class_method(cls, *args, **kwds):
pass
Быстрое взлома одних и тех же методов в iPython показывает, что @staticmethod
дает предельный прирост производительности (в наносекундах), но в остальном он, похоже, не функционирует. Кроме того, любые улучшения производительности, вероятно, будут уничтожены дополнительной работой по обработке метода через staticmethod()
во время компиляции (что происходит до выполнения любого кода при запуске скрипта).
Ради читаемость кода Я бы избегал @staticmethod
, если ваш метод не будет использоваться для нагрузок работы, где подсчитываются наносекунды.
Окончательное руководство по использованию статических, классных или абстрактных методов в Python является одной из хороших ссылок для этой темы и сводит их к следующему:
@staticmethod
function это не что иное, как функция, определенная внутри класса. Он может быть вызван без создания экземпляра класса. Это определение является неизменным с помощью наследования.
@classmethod
функция также может быть вызвана без создания экземпляра класса, но ее определение следует подкласс Sub, а не родительский класс, через наследование, может быть переопределено подклассом. Это потому, что первый аргумент для функции @classmethod
всегда должен быть cls (класс).
Официальные документы python:
Метод класса получает класс как неявный первый аргумент, как и метод экземпляра экземпляр. Чтобы объявить метод класса, используйте эту идиому:
class C: @classmethod def f(cls, arg1, arg2, ...): ...
Форма
@classmethod
является функцией decorator - см. Описание определений функций в Определения функций для деталей.Он может быть вызван либо в классе (например,
C.f()
), либо в экземпляре (например,C().f()
). Экземпляр игнорируется, за исключением его класса. Если метод класса вызывается для производного класса, объект производного класса передается как предполагаемый первый аргумент.Методы класса отличаются от статических методов C ++ или Java. Если вы хотите их, см.
blockquote>staticmethod()
в этом разделе.Статический метод не получает неявный первый аргумент. Чтобы объявить статический метод, используйте эту идиому:
class C: @staticmethod def f(arg1, arg2, ...): ...
Форма
@staticmethod
является функцией decorator - см. Описание определений функций в Определения функций для деталей.Его можно вызвать либо в классе (например,
C.f()
), либо в экземпляре (например,C().f()
). Экземпляр игнорируется, за исключением его класса.Статические методы в Python аналогичны тем, которые были найдены в Java или C ++. Для более продвинутой концепции см.
blockquote>classmethod()
в этом разделе.
Мой вклад демонстрирует разницу между методами @classmethod
, @staticmethod
и экземплярами, включая то, как экземпляр может косвенно вызвать @staticmethod
. Но вместо косвенного вызова @staticmethod
из экземпляра, делая его частным, может быть более «питоническим». Получение чего-то из частного метода здесь не показано, но в принципе это та же концепция.
#!python3
from os import system
system('cls')
# % % % % % % % % % % % % % % % % % % % %
class DemoClass(object):
# instance methods need a class instance and
# can access the instance through 'self'
def instance_method_1(self):
return 'called from inside the instance_method_1()'
def instance_method_2(self):
# an instance outside the class indirectly calls the static_method
return self.static_method() + ' via instance_method_2()'
# class methods don't need a class instance, they can't access the
# instance (self) but they have access to the class itself via 'cls'
@classmethod
def class_method(cls):
return 'called from inside the class_method()'
# static methods don't have access to 'cls' or 'self', they work like
# regular functions but belong to the class' namespace
@staticmethod
def static_method():
return 'called from inside the static_method()'
# % % % % % % % % % % % % % % % % % % % %
# works even if the class hasn't been instantiated
print(DemoClass.class_method() + '\n')
''' called from inside the class_method() '''
# works even if the class hasn't been instantiated
print(DemoClass.static_method() + '\n')
''' called from inside the static_method() '''
# % % % % % % % % % % % % % % % % % % % %
# >>>>> all methods types can be called on a class instance <<<<<
# instantiate the class
democlassObj = DemoClass()
# call instance_method_1()
print(democlassObj.instance_method_1() + '\n')
''' called from inside the instance_method_1() '''
# # indirectly call static_method through instance_method_2(), there's really no use
# for this since a @staticmethod can be called whether the class has been
# instantiated or not
print(democlassObj.instance_method_2() + '\n')
''' called from inside the static_method() via instance_method_2() '''
# call class_method()
print(democlassObj.class_method() + '\n')
''' called from inside the class_method() '''
# call static_method()
print(democlassObj.static_method())
''' called from inside the static_method() '''
"""
# whether the class is instantiated or not, this doesn't work
print(DemoClass.instance_method_1() + '\n')
'''
TypeError: TypeError: unbound method instancemethod() must be called with
DemoClass instance as first argument (got nothing instead)
'''
"""
Я думаю, что лучший вопрос: «Когда вы будете использовать @classmethod vs @staticmethod?»
@classmethod позволяет вам легко получить доступ к закрытым членам, которые связаны с определением класса. это отличный способ сделать одиночные игры или фабричные классы, которые контролируют количество экземпляров созданных объектов.
@staticmethod обеспечивает предельный прирост производительности, но мне еще предстоит увидеть продуктивное использование статического метод внутри класса, который не может быть выполнен как автономная функция вне класса.
Я попытаюсь объяснить основное различие с помощью примера.
class A(object):
x = 0
def say_hi(self):
pass
@staticmethod
def say_hi_static():
pass
@classmethod
def say_hi_class(cls):
pass
def run_self(self):
self.x += 1
print self.x # outputs 1
self.say_hi()
self.say_hi_static()
self.say_hi_class()
@staticmethod
def run_static():
print A.x # outputs 0
# A.say_hi() # wrong
A.say_hi_static()
A.say_hi_class()
@classmethod
def run_class(cls):
print cls.x # outputs 0
# cls.say_hi() # wrong
cls.say_hi_static()
cls.say_hi_class()
1 - мы можем напрямую вызвать статические и классные методы без инициализации
# A.run_self() # wrong
A.run_static()
A.run_class()
2- Статический метод не может вызвать метод self, но может вызывать другие static и classmethod
. 3 Статический метод принадлежит классу и вообще не будет использовать объект.
4- Метод класса не привязан к объекту но классу.
Позвольте мне сначала сказать сходство между методом, украшенным с помощью метода @classmethod vs @staticmethod.
Сходство: оба они могут быть вызваны самим классом Class , а не только экземпляр класса. Таким образом, оба они в некотором смысле являются методами класса .
Разница: класс-метод получит сам класс как первый аргумент, в то время как staticmethod не делает.
Таким образом, статический метод, в некотором смысле, не связан с самим классом и просто висит там только потому, что может иметь связанную функциональность.
>>> class Klaus:
@classmethod
def classmthd(*args):
return args
@staticmethod
def staticmthd(*args):
return args
# 1. Call classmethod without any arg
>>> Klaus.classmthd()
(__main__.Klaus,) # the class gets passed as the first argument
# 2. Call classmethod with 1 arg
>>> Klaus.classmthd('chumma')
(__main__.Klaus, 'chumma')
# 3. Call staticmethod without any arg
>>> Klaus.staticmthd()
()
# 4. Call staticmethod with 1 arg
>>> Klaus.staticmthd('chumma')
('chumma',)
В основном @classmethod
создает метод, первым аргументом которого является класс, из которого он вызывается (а не экземпляр класса), @staticmethod
не имеет никаких неявных аргументов.
Здесь - короткая статья по этому вопросу
Функция @staticmethod - это не что иное, как функция, определенная внутри класса. Он может быть вызван без создания экземпляра класса. Это определение является неизменным с помощью наследования.
Функция @classmethod также может быть вызвана без создания экземпляра класса, но ее определение следует через класс Sub, а не родительский класс, через наследование. Это потому, что первым аргументом для функции @classmethod всегда должен быть cls (класс).
blockquote>
Методы класса, как следует из названия, используются для внесения изменений в классы, а не в объекты. Чтобы внести изменения в классы, они будут изменять атрибуты класса (а не атрибуты объекта), поскольку именно так вы обновляете классы. Это причина, по которой методы класса принимают класс (условно обозначаемый «cls») как первый аргумент.
class A(object):
m=54
@classmethod
def class_method(cls):
print "m is %d" % cls.m
Статические методы, с другой стороны, используются для выполнения функций, которые не связаны с класс, т.е. они не будут читать или писать переменные класса. Следовательно, статические методы не принимают классы в качестве аргументов. Они используются таким образом, чтобы классы могли выполнять функциональные возможности, которые напрямую не связаны с целью класса.
class X(object):
m=54 #will not be referenced
@staticmethod
def static_method():
print "Referencing/calling a variable or function outside this class. E.g. Some global variable/function."
@classmethod означает: когда этот метод вызывается, мы передаем класс в качестве первого аргумента вместо экземпляра этого класса (как обычно мы делаем с методами). Это означает, что вы можете использовать класс и его свойства внутри этого метода, а не конкретный экземпляр.
@staticmethod означает: когда этот метод вызывается, мы не передаем ему экземпляр класса (as мы обычно делаем с методами). Это означает, что вы можете поместить функцию внутри класса, но вы не можете получить доступ к экземпляру этого класса (это полезно, когда ваш метод не использует экземпляр).
@classmethod: может использоваться для создания общего глобального доступа ко всем экземплярам, созданным из этого класса ..... например, для обновления записи несколькими пользователями ... Я особенно нашел, что это полезно при создании синглетов ..:)
@статический метод: не имеет ничего общего с классом или экземпляром, связанным с ... но для чтения может использовать статический метод
#!/usr/bin/python
#coding:utf-8
class Demo(object):
def __init__(self,x):
self.x = x
@classmethod
def addone(self, x):
return x+1
@staticmethod
def addtwo(x):
return x+2
def addthree(self, x):
return x+3
def main():
print Demo.addone(2)
print Demo.addtwo(2)
#print Demo.addthree(2) #Error
demo = Demo(2)
print demo.addthree(2)
if __name__ == '__main__':
main()
@staticmethod
может помочь организовать ваш код, будучи переопределяемым подклассами. Без этого у вас будут варианты функции, плавающие в пространстве имен модулей. – unutbu 19 September 2011 в 11:34However, class methods are still useful in other places, for example, to program inheritable alternate constructors.
. Даже оригинальная цитата очень вводит в заблуждение, поскольку он только сказал, что Распределение python не используетclassmethod
. Но только потому, что сам python не использует данную функцию, это не значит, что это бесполезная функция. Подумайте о комплексных числах или даже sqrt : сам python тоже не может использовать, но это далеко не бесполезно предлагать – MestreLion 3 May 2012 в 11:44