2012-01-22 2 views
3

Я создаю библиотеку различных функций, которые часто будут повторно использоваться в проекте. Каждая функция не имеет состояния (не требует параметров при создании и не имеет никакой памяти). Некоторые функции используют другие.python: дизайн библиотеки функций без гражданства

Эти функции будут переданы в качестве аргументов в остальной части проекта.

Какой из следующих подходов лучше?

1.Define все функции как глобальные функции в определенном модуле:

def f1(x): 
    # use x 

def f2(x): 
    # use x and f1 

2.Define все функции, как методы в классах, а также организовать классы в иерархии, основанные на использовании:

class F1: 
    def __call__(x): 
    # use x 

f1 = F1() 

class F2(F1): 
    def __call__(x): 
    # use x and f1 

f2 = F2() 

Причина, по которой я даже рассматривал вариант 2, состоит в том, что некоторые из моих функций имеют что-то общее. Например, функции f2, f3, f11 все начинается по телефону f1. Я думал, я мог бы сделать что-то вроде этого:

class F1: 
    def __call__(self, x): 
    self.f1(x) 
    self.calc(x) 
    def f1(self, x): 
    # do something 
    # don't define calc here; F1 is abstract base class 

class F2(F1): 
    def calc(self, x): 
    # do something 

class F3(F1): 
    def calc(self, x): 
    # do something 
+3

Где у вас была идея сделать 2? –

+0

@FrancisAvila: см. Мой обновленный вопрос, чтобы объяснить мое мышление. – max

+0

Вы имели в виду, что 'F2' и' F3' продлевать 'F1'? Это не то, что говорит код ... –

ответ

2

Вариант 1 является более простым. Вариант 2 бесполезно сложный!

Еще одно предложение, которое может облегчить тестирование:

1,1. Определите их как методы одного класса в одном модуле. При необходимости используйте декораторы @staticmethod и @classmethod. Это может упростить замену с помощью mocks или переопределить альтернативные реализации, предоставив новый класс или подкласс позже.

spam.py:

class Spam(object): 
    @staticmethod 
    def f1(x): 
    # use x 

    @classmethod 
    def f2(cls, x): 
    # use x and cls.f1 

Это еще более сложным, так что вы можете просто хотите придерживаться вариант 1 до тех пор, пока есть необходимость для выше.

+0

То, что вы предлагаете с помощью '@ classmethod', похоже на то, о чем я думал. Я не хотел, чтобы все было '@ classmethod', так как я думал, что однажды мне захочется добавить состояние к функции; так как я все-таки писал классы, почему бы не оставить гибкость для этой потенциальной потребности? – max

+0

Есть способы заменить функцию классом или объектом, если требуется наличие состояния без изменения API. – kindall

+0

@kindall: ах это правда. Я не думал об этом. Это довольно просто - просто используйте '__call__'? – max

2

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

3

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

Смежные вопросы