在继承时从超类实例复制属性?

时间:2016-07-31 23:50:33

标签: python inheritance subclass python-3.4 superclass

我正在尝试创建一个继承自其超类实例的子类,并将其大部分属性基于超类属性。

Func<int[],bool> cond = xs => true;

int[] sarr = new int[] { 0, 1, 3, 5, }; 

var result =
    getAllSubsets(sarr)
        .Where(xs => xs.Count() == 2)
        .Where(xs => cond(xs.ToArray()));

是否有更简洁的方法在class Thing: def __init__(self, a, b, c): self.a = a self.b = b self.c = c class ThingWithD(Thing): def __init__(self, thing, d): self.a = thing.a self.b = thing.b self.c = thing.c self.d = d 内制作abc声明?

2 个答案:

答案 0 :(得分:2)

最简洁和面向对象的方式可能是调用超类的__init__()方法并避免重复:

class Thing:
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

class ThingWithD(Thing):
    def __init__(self, thing, d):
        super().__init__(thing.a, thing.b, thing.c)  # Python 3 only
        self.d = d

thing = Thing(1, 2, 3)
thing_with_d = ThingWithD(thing, 4)
print('{}, {}'.format(thing_with_d.a, thing_with_d.d)) # -> 1, 4

要在Python 2.x中执行相同的操作,您需要通过将其基类明确指定为Thing来使object成为新式类,并将对超类构造函数的调用更改为如下所示。

如果同时进行这两项修改,相同的代码将在Python 2和3中都有效。

class Thing(object):
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

class ThingWithD(Thing):
    def __init__(self, thing, d):
        super(ThingWithD, self).__init__(thing.a, thing.b, thing.c)
        self.d = d

答案 1 :(得分:1)

将类Thing定义为:

class Thing:
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

我可以想到使用经典继承来实现你所要求的3种方法。第一个是利用你已知的参数并明确地将args索引为a,而d,就像这样:

class ThingWithD(Thing):
    def __init__(self, *args):
        self.d = args[-1]
        a_to_c = args[:-1]
        super().__init__(*a_to_c)


thing_with_d = ThingWithD(1,2,3,4)
thing_with_d.a # 1
thing_with_d.d # 4

第二种也是最好的方法是将你的参数转换为关键字参数,以便更容易混合和匹配。这是最具扩展性的解决方案,可为ThingWithEThingWithF铺平道路。

class ThingWithD(Thing):
    def __init__(self, d=None, **kwargs):
        super().__init__(**kwargs)
        self.d = d


thing_with_d = ThingWithD(a=1,b=2,c=3,d=4)
thing_with_d.a # 1
thing_with_d.d # 4

最后一种方式,似乎与您已经尝试过的方式最接近的方法是使用ThingWithD作为工厂类,将d自我引用添加到类中。

class ThingWithD(Thing):
    def __init__(self, thing, d):
        super().__init__(thing.a, thing.b, thing.c)
        self.d = d

thing = Thing(1,2,3)
thing_with_d = ThingWithD(thing, 4)
thing_with_d.a # 1
thing_with_d.d # 4

这是一种奇怪的方法,因为我们实际上是在创建原始thing实例的副本,而且我们还不清楚为什么我们会继承Thing。相反,我们可以使用执行以下操作的函数。

def add_d_to_thing(thing, d):
    thing.d = d
    return thing

thing = Thing(1,2,3)
thing_with_d = add_d_to_thing(thing, 4)
thing_with_d.a # 1
thing_with_d.d # 4

这会返回相同的事物实例,会添加d属性,并且更容易阅读。