функции фабрики Python по сравнению с классом - PullRequest
18 голосов
/ 23 мая 2009

Просто работал через изучение Python и начал смотреть на вложенные / фабричные функции (простой пример):

def maker(N):
    def action(X):
        return X * N
    return action

Есть ли какие-либо преимущества фабричных функций перед созданием класса? спектакль? объем памяти? убирать?

Ответы [ 3 ]

26 голосов
/ 23 мая 2009

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

class clsmaker(object):
    def __init__(self, N):
        self.N = N
    def __call__(self, X):
        return X * self.N

Это не так уж плохо, пока вы не начнете добавлять аргументы в конструктор. Затем, делая это классным способом, получает дополнительную строку для каждого аргумента, тогда как функция просто получает дополнительные аргументы.

Оказывается, что у вложенных функций есть преимущество в скорости:

>>> T1 = timeit.Timer('maker(3)(4)', 'from __main__ import maker')
>>> T1.timeit()
1.2818338871002197
>>> T2 = timeit.Timer('clsmaker(3)(4)', 'from __main__ import clsmaker')
>>> T2.timeit()
2.2137160301208496

Это может быть связано с тем, что в версии для вложенных функций используется меньше операционных кодов:

>>> dis(clsmaker.__call__)
  5           0 LOAD_FAST                1 (X)
              3 LOAD_FAST                0 (self)
              6 LOAD_ATTR                0 (N)
              9 BINARY_MULTIPLY     
             10 RETURN_VALUE        
>>> act = maker(3)
>>> dis(act)
  3           0 LOAD_FAST                0 (X)
              3 LOAD_DEREF               0 (N)
              6 BINARY_MULTIPLY     
              7 RETURN_VALUE  
13 голосов
/ 24 мая 2009

Сравнение фабрики функций с классом - это сравнение яблок и апельсинов. Используйте класс, если у вас есть сплоченная коллекция данных и функций, которые вместе называются объектом. Используйте фабрику функций, если вам нужна функция и вы хотите параметризовать ее создание.

Ваш выбор двух методов должен зависеть от значения кода.

3 голосов
/ 23 мая 2009

Вложенные функции позволяют создавать пользовательские функции на лету.

Посмотрите, например, декораторы . Результирующие функции зависят от переменных, которые связаны во время создания и не нуждаются в последующем изменении. Так что использование класса для этой цели имело бы меньше смысла.

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