init成员的最佳实践

时间:2013-10-02 10:45:52

标签: python oop

我对初始化课程的最佳做法有疑问。考虑一个复杂的类,并且有很多成员。在__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"

...

1 个答案:

答案 0 :(得分:0)

我也同意拥有太多属性可能是抽象不足的标志,这通常难以开发和放大。调试,所以改变你的设计可能是一个好主意。

但是,你确实有一枚金徽章,所以你显然已经到处并且(可能)知道你在做什么,并且可能有理由这样做。在这种情况下,我认为像你建议的那样按类别拆分初始化是个好主意。我唯一的建议就是在子初始化函数上使用_来向用户发出信号,表明它们不是正常使用的,即

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

    self.__init_other_stuff()

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

等。这也隐藏了大多数游戏机中的标签完成功能。编辑。

你的另一个选择是让这个类成为实现部分接口的多个类的子类,如果你真的需要A直接包含这些项,即做这样的事情:

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。尽管恕我直言,多重继承在概念上稍微复杂一些。