Страницы

Поиск по вопросам

среда, 15 мая 2019 г.

В чем разница между статической функцией и функцией указанной в классе (не метод класса с (self))

class Robot: def sayHi(): print("Hi")
class Robot: @staticmethod def sayHi(): print("Hi")
В чем разница ? При вызове Robot.sayHi() оба работают.
PS: понимаю, что вопрос глупый, но не удается найти ответ (вероятно не знаю как правильно задать вопрос)


Ответ

Оба приведенных примера определяют класс со статическим методом. Разница лишь в том, что во втором случае вы используете декоратор @staticmethod, который явно указывает, что метод статичный.
Когда у класса есть статические методы, логично предположить, что они будут вызваны "от класса", а не от объекта этого класса:
class Robot: def sayHi(): print("Hi")
Robot.sayHi()
Но если мы вызовем этот же метод от объекта:
robot = Robot() robot.sayHi()
То получим ошибку:
Traceback (most recent call last): File ".../main.py", line 9, in robot.sayHi() TypeError: sayHi() takes 0 positional arguments but 1 was given
Почему так происходит?
Потому что вызов robot.sayHi() равносилен вызову Robot.sayHi(robot), а поскольку данный метод ничего не принимает - возникает ошибка из-за передачи объекта класса неявным первым аргументом.

Отдельно стоит упомянуть о @staticmethod из документации:
A static method does not receive an implicit first argument. To declare a static method, use this idiom:
class C: @staticmethod def f(arg1, arg2, ...): ... The @staticmethod form is a function decorator – see the description of function definitions in Function definitions for details. It can be called either on the class (such as C.f()) or on an instance (such as C().f()). The instance is ignored except for its class. Static methods in Python are similar to those found in Java or C++. For a more advanced concept, see classmethod() in this section.
Как видно из документации, данный декоратор "явно" делает метод статичным. Однако его все еще можно вызвать, используя объект: robot().sayHi(), но в этот раз никакой ошибки не будет и данный вызов будет равносилен Robot.sayHi() - учитывается только тип вызываемого объекта.

Комментариев нет:

Отправить комментарий