#python #python-3.x #python-decorators
#python #python-3.x #python-декораторы
Вопрос:
Что я могу сделать с Python 3.x, bar()
с чем я не могу foo()
?
class A:
def foo():
print("some code")
@staticmethod
def bar():
print("some code")
Примечание: Изначально я забыл указать self
в качестве аргумента foo()
, но я оставляю ошибку там, поскольку ответы подчеркивают это.
Комментарии:
1. Определение
foo
должно бытьdef foo(self):
, если вы планируете его вызывать 🙂2. это недопустимо. foo завершится ошибкой, поскольку для этого требуется ссылка на self
foo(self)
3. Пожалуйста, не меняйте вопрос, я уже обратился к вашей первоначальной версии — и ее стоит оставить в ответе..
4. Разница становится очевидной, как только
self
добавляется в качестве аргумента. Функция никогда бы не запустилась безself
в любом случае5. Итак, должен ли я вернуть его к исходному виду с ошибкой и оставить заметку для редактирования, чтобы какой-нибудь другой ученик мог ее подхватить?
Ответ №1:
staticmethod
— это метод, который не требует объекта в качестве своего первого параметра. Это означает, что это метод, полезный для самого класса и всех его экземпляров, а не просто для его экземпляров (объект инициализирован как A()
.
На практике это означает, что Python неявно отправляет сам объект в качестве параметра. Ваш первый метод сломается, как только вы его вызовете:
>>> a.foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes 0 positional arguments but 1 was given
Это потому, что Python предоставляет объектные методы с самим объектом в качестве первого параметра. Отсюда повсеместный аргумент self:
def foo(self): #Proper signature
С другой стороны,
A.bar()
будет работать просто отлично, и так будет
a.bar()
Объект не предоставляется в качестве первого аргумента. Используйте staticmethod
s для методов, которые должны быть полезны для класса и его экземпляров, но не требуют знания ни того, ни другого. Обычно я использую их как служебные функции.
Обратите внимание, что существует третья версия, a classmethod
, которая похожа на обычный метод в том, что она принимает первый параметр по умолчанию — класс вызывающего. В этом случае минимальная сигнатура равна
@classmethod
def operateOnClass(cls):
Используйте это для внесения изменений, которые влияют на все экземпляры, например, для изменения переменных класса.
Комментарии:
1. Возможно, важно упомянуть, что в python есть три типа методов: методы экземпляра, методы класса и статические методы.
2. Да, пожалуйста, уточните это, чтобы я мог получить более полную картину
3. @Будет выполнено. Каждый из них полезен для чего-то немного другого.
Ответ №2:
bar()
может вызываться из не созданного объекта класса. foo()
должен быть передан self
в качестве аргумента и, как таковой, может быть вызван только из объекта, уже объявленного как экземпляр class A