2013-10-02 3 views
0

У меня есть вопрос о лучших методах инициализации класса. Рассмотрим класс, который является сложным и имеет множество членов. Неплохая практика - инициировать их за пределами __init__(), но как я могу справиться с этой проблемой, не имея огромного метода __init__().Лучшая практика для элемента init

Пример:

class A: 
    def __init__(self): 
     self.member0 = "a" 

     # to prevent that the init method gets too big 
     # put some initialisation outside 
     init_other_stuff() 

    def init_other_stuff(self): 
     self.member1 = "b" 
     self.member2 = "c" 
     ... 

Спасибо заранее.

[обновление] Чтобы уточнить. Цель состоит не в том, чтобы положить материал в другой длинный метод, конечно. Вместо этого вы можете разделить инициализацию на различные части, как:

def init_network_stuff(self): 
    """ init network setup """ 
    self.my_new_socket = socket.socket(..) 


def init_local_stuff(self): 
    """ init local setup """ 
    self.my_new_logpath = "/foo/bar/log" 

... 
+5

Трудно дать определенный ответ. По-моему, просто отключить '__init __()' и переместить остальную часть функции в другую функцию просто, чтобы она не стала слишком длинной, совершенно бессмысленно. Кроме того, я считаю, что класс с большим количеством участников является признаком проблемы дизайна сам по себе. –

+6

* Рассмотрите класс, который является сложным и имеет много членов. * Это ваша проблема прямо там. Класс не должен иметь столько атрибутов. Возможно, вам стоит взглянуть на переработку вашей системы классов. – Oin

+0

, поэтому, чтобы избежать длинного __init__, вы перемещаете его содержимое на другой длинный метод (который любой мог вызвать, не понимая, действительно ли это метод init?) – njzk2

ответ

0

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

Но у вас есть золотой значок, так что вы, очевидно, были вокруг и (возможно) знаете, что делаете, и, возможно, есть причина сделать это. В этом случае, я думаю, что это хорошая идея, чтобы разделить инициализацию по категориям, как вы предложили. Единственное предложение, которое я бы это использовать _ на суб-инициализации функций, чтобы сигнализировать пользователю они не предназначены для использования в обычных т.е.

class A: 
def __init__(self): 
    self.member0 = "a" 

    self.__init_other_stuff() 

def __init_other_stuff(self): 
    self.member1 = "b" 
    self.member2 = "c" 

и т.д. Это также скрывает их от вкладки-завершения в большинстве консолей & редакторов.

Ваш другой выбор, чтобы сделать этот класс подкласс нескольких классов, реализующих часть интерфейса, если вам действительно нужно, чтобы содержать эти элементы непосредственно, то есть сделать что-то вроде этого:

class Logger(object): 
    def __init__(self): 
     self.logparam = 1 

class NetworkSource(object): 
    def __init__(self): 
     self.netparam = 2 

class A(Logger, NetworkSource): 
    def __init__(self): 
     Logger.__init__(self) 
     NetworkSource.__init__(self) 

In [2]: a = A() 

In [3]: a.<tab> 
a.logparam a.netparam 

Тогда бы получить функциональность обоих классов, имея относительно короткий init. Множественное наследование концептуально немного сложнее, хотя ИМХО.

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