我想要父母和子女 使用父实例初始化子类。 我的方式似乎很麻烦(见下文):
我定义了一个静态方法来提取父级初始化的init
参数:
class Parent(object):
@staticmethod
get_init_params(parent_obj):
a = parent_obj.a
b = parent_obj.b
return (a, b)
def __init__(self, a, b):
self.a = a
self.b = b
class Child(Parent):
def __init__(self, parent):
super(Parent, self).__init__(*get_init_params(parent))
是否有更直接的方式?
编辑现在课程更简单
答案 0 :(得分:5)
我认为您希望将初始化 Child
对象的概念与<{>创建的概念从Parent
分开。 get_init_params
只是增加了一层你不需要的复杂性;直接访问属性。
class Child(Parent):
@classmethod
def from_parent(cls, parent):
return cls(parent.a, parent.b)
def __init__(self, a, b):
super(Child, self).__init__(a, b)
# Note: the fact that yo have to do this,
# or not call the parent's __init__ in the first
# place, makes me question whether inheritance
# is the right tool here.
self.a = revert_change(self.a)
self.b = revert_change(self.b)
p = Parent(3, 5)
c1 = Child.from_parent(p)
c2 = Child(6, 6)
如果您对来自父级的值进行了更改,请在创建to_parent
对象之前将其应用于Child
。
def from_parent(cls, parent):
return cls(revert_change(parent.a), revert_change(parent.b))
# Or, if you save the original values
# return cls(parent.orig_a, parent.orig_b)
答案 1 :(得分:1)
根据您在原始答案中的评论,我相信您不想继承Parent
;相反,你只需要替代构造函数。
class Parent(object):
# The basic initializer; just use whatever values are
# passed directly to it
def __init__(self, a, b):
self.a = a
self.b = b
@classmethod
def type_1(cls, a, b):
return cls(change_a1(a), change_b1(b))
@classmethod
def type_2(cls, a, b):
return cls(change_a2(a), change_b2(b))
# etc
如果你真的做想要一个Parent
的子类,那么就没有必要退出任何变化; Parent
仅包含适用于所有子项的功能。
class Child(Parent):
def __init__(self, a, b):
super(Child, self).__init__(a, b)
# Any Child-specific initialization
答案 2 :(得分:0)
为什么不保存init参数并在Parent
到make_child()
上创建新的绑定方法?
class Parent(object):
def __init__(self, *args, **kwargs):
self.init_args = {'args':args, 'kwargs':kwargs}
self.children = list()
... # whatever else a Parent does
def make_child(self, child_cls, *args, **kwargs):
if args is None:
args = self.init_args['args']
if kwargs is None:
kwargs = self.init_args['kwargs']
child = child_cls(self, *args, **kwargs)
self.children.append(child)
return child
class Child(Parent):
def __init__(self, parent, *args, **kwargs):
self.parent = parent
... # whatever else a Child does
样本
>>> p = Parent()
>>> c = p.make_child(Child)
>>> c in p.children
True
答案 3 :(得分:-1)
让你的父(以及子)构造函数改变a和b。您应该尽可能少地使用init方法中的行为。创建一个不改变a和b的类方法,更改它们,然后将类构造函数应用于它们 - 这对父和子都有好处。然后在子类上编写一个静态方法,该子类接受父对象,并将其更改的a和b属性传递给期望更改a和b的init方法。
class Parent(object):
@classmethod
def from_unchanged(cls, a, b):
changed_a = change_a(a)
changed_b = change_b(b)
return cls(a, b)
@classmethod
def from_parent(cls, parent):
return cls(parentchanged_a, parentchanged_b)
def __init__(self, changed_a, changed_b) :
selfchanged_a = changed_a
selfchanged_b = changed_b