Необходимость использования статических методов вместо подфункций в функции - PullRequest
0 голосов
/ 27 апреля 2018

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

Рассмотрим этот пример ниже (пересмотрено с Полное руководство по использованию статических, классовых или абстрактных методов в Python ):

class Pizza(object):
    def __init__(self, cheese, vegetables):
        self.cheese = cheese
        self.vegetables = vegetables

    @staticmethod
    def mix_ingredients(x, y):
        return x + y

    def cook(self):
        return self.mix_ingredients(self.cheese, self.vegetables)

Почему бы и нет:

def cook_pizza(cheese, vegetables):
    def mix_ingredients(x, y):
        return x + y
    return mix_ingredients(cheese, vegetables)

В этом примере я бы использовал функцию cook в Pizza. Допустим, в будущем нет других функций, которые я бы определил в Pizza, т. Е. Я готовлю только с пиццей. Разве я не могу просто определить это как одну единственную функцию cook_pizza? Таким образом, mix_ingredients не будет глобальным и не будет иметь конфликтов имен с другими экземплярами.

Есть ли какие-либо преимущества или недостатки, которые записаны как @staticmethod в этом случае? Например, Pizza(cheese, vegetables).cook() работает лучше, чем cook_pizza(cheese, vegetables), потому что первый не должен определять mix_ingredients каждый раз в процессе?

1 Ответ

0 голосов
/ 27 апреля 2018

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

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

Метод

Без создания экземпляра:

In [2]: Pizza.cook()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-4a252d4e9619> in <module>()
----> 1 Pizza.cook()

TypeError: cook() missing 1 required positional argument: 'self'

С экземпляром:

In [4]: Pizza('cheese', 'vegetables').cook()
Out[4]: 'cheesevegetables'

Статический метод

Без создания экземпляра:

In [5]: Pizza.mix_ingredients(1,2)
Out[5]: 3

Производительность:

Каждый раз, когда вы вызываете cook_pizza, он определяет вложенную функцию, которая влияет на время выполнения.

import timeit

def method():
    return 'method'

def method_with_inner():
    def inner():
        return 'inner'
    return inner()

Исполнение

 print(timeit.timeit("method()", setup="from __main__ import method"))

+0,0910306089790538

print(timeit.timeit("method_with_inner()", setup="from __main__ import method_with_inner"))

0,24090809898916632

примечание

cook_pizza может быть статическим методом, так как он не использует переменную, определенную на уровне класса или хранилище в себе.

Спасибо: @Shadow @abarnert за вклад в ветку обсуждения этого ответа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...