除一个

时间:2016-07-04 18:32:21

标签: python class oop inheritance

我有一种情况,基类方法(Python中的__init__方法)做了很多工作。派生类重写__init__以简单地设置对象变量,然后委托给基类__init__。这很好但现在我有一个情况。

我有一些完全适合基类__init__的代码,除了一个(称之为A)之外的所有其他派生类都需要使用。想象一下,如果基类__init__是这样的话。

def __init__(self):
   Action 1...
   Action 2...

现在,所有派生类都只是直接委托给它。但是,A的{​​{1}}中应该只有 操作2。现在这个人很难看。我可以将Action 1和Action 2分成两个独立的函数,让基类只需调用__init__。然后大多数类将使用这样的init。

Action2

,对于班级def __init__(self): self.Action1() Other init code... super().__init__() ,它将是

A

但是你可以看到有一段代码(对def __init__(self): Some init code.... super().__init__() 的调用)我必须在大多数派生类中重复。这是不好的。我不知道如何用最少的重复代码优雅地编写代码,并且需要一些关于如何执行它的建议。

3 个答案:

答案 0 :(得分:3)

最明确的解决方案是使用默认参数:

text.on.each.panel <-"_new"
d <- ggplot(diamonds, aes(carat, price)) +
     xlim(0, 2) 
d + facet_wrap(~ color, labeller = label_bquote(.(color)-.(text.on.each.panel)))

然后在课程class Base: def __init__(self, *, doAction1=True): if doAction1: Action 1... Action 2... 中你可以:

A

答案 1 :(得分:0)

可以覆盖的类属性 - 类似于__init__中的默认参数。 (Python v2.7类定义)。

class Foo(object):
   action1 = True
   action2 = True
   def __init__(self):
      if self.action1:
         print('action1')
      if self.action2:
         print('action2')

class Bar(Foo):
   def __init__(self):
      super(Bar, self).__init__()
      print('Bar')

class Baz(Foo):
   action2 = False
   def __init__(self):
      super(Baz, self).__init__()
      print('Baz')

答案 2 :(得分:0)

在做出设计决策时,通常值得考虑继承是否是正确的方法。深入思考你是否真的需要继承,或者它是否会让事情变得复杂。

如果您决定实际上不需要继承(您询问的当前问题可能 - 或者可能不是这种情况的迹象),在诉诸继承之前,我建议您探索解决您的问题像这样的东西:

def Action1(obj):
    <do Action 1>

def Action2(obj):
    <do Action 2>

def Action1and2(obj):
    Action1(obj)
    Action2(obj)

class A:
    def __init__(self):
        Action2(self)

class Other:
    def __init__(self):
        Action1and2(self)

请注意,对于Other个对象,您仍然只有一行代码,并且您完全避免了继承。

如果您决定继承是必需的 - 也就是说,您创建的父对象不仅仅是通过某些操作进行设置(它们提供额外的功能或访问数据) - 您可以尝试使用组成,而不是像这样:

class Action1Doer:
    def __init__(self,obj):
        <do Action 1>

class Action2Doer:
    def __init__(self,obj):
        <do Action 2>

class Action1and2Doer:
    def __init__(self,obj):
        self.a1 = Action1Doer(obj)
        self.a2 = Action2Doer(obj)

class A:
    def __init__(self):
        self.thing2 = Action2Doer(self)

class Other:
    def __init__(self):
        self.thing1and2 = Action1and2Doer(self)

请注意,同样,每个初始化方法中只有一行代码。顺便说一下,在编码世界中以这种方式处理事情is certainly nothing new

你也可以把事情混合在一起:

def Action1(obj):
    <do Action 1>

class Action2Doer:
    def __init__(self,obj):
        <do Action 2>

class Action1and2Doer:
    def __init__(self,obj):
        Action1(obj)
        self.a2 = Action2Doer(obj)

class A:
    def __init__(self):
        self.thing2 = Action2Doer(self)

class Other:
    def __init__(self):
        self.thing2 = Action1and2Doer(self).a2