继承时从超类实例复制属性?
Copying Attributes from Superclass Instance while Inheriting?
我正在尝试创建一个继承自其超类实例的子类,并将其大部分属性基于超类属性。
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
在ThingWithD.__init__()
中声明a
、b
和c
有没有更简洁的方法?
class Thing
定义为:
class Thing:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
我可以想到 3 种方法来使用 classical 继承来实现您的要求。首先,是利用您已知的参数并显式索引 args
以提取 a 到 c 和 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
第二种也是最好的方法是将参数转换为关键字参数,以便更轻松地混合和匹配它们。这是最具可扩展性的解决方案,可以为 ThingWithE
和 ThingWithF
铺平道路。
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
作为工厂 class 将 d 添加到 class self referentially。
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
这将 return 相同的事物实例,将添加一个 d
属性,并且更易于阅读。
最简洁和面向对象的方法可能是只调用 superclass 的 __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 中做同样的事情,您需要通过明确指定其基础 class 使 Thing
成为新样式 class ] 作为 object
并更改对 superclass 构造函数的调用,如下所示。
如果您进行这两项修改,相同的代码将在 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
我正在尝试创建一个继承自其超类实例的子类,并将其大部分属性基于超类属性。
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
在ThingWithD.__init__()
中声明a
、b
和c
有没有更简洁的方法?
class Thing
定义为:
class Thing:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
我可以想到 3 种方法来使用 classical 继承来实现您的要求。首先,是利用您已知的参数并显式索引 args
以提取 a 到 c 和 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
第二种也是最好的方法是将参数转换为关键字参数,以便更轻松地混合和匹配它们。这是最具可扩展性的解决方案,可以为 ThingWithE
和 ThingWithF
铺平道路。
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
作为工厂 class 将 d 添加到 class self referentially。
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
这将 return 相同的事物实例,将添加一个 d
属性,并且更易于阅读。
最简洁和面向对象的方法可能是只调用 superclass 的 __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 中做同样的事情,您需要通过明确指定其基础 class 使 Thing
成为新样式 class ] 作为 object
并更改对 superclass 构造函数的调用,如下所示。
如果您进行这两项修改,相同的代码将在 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