如何在 Python 中的 child class 中略微修改 parent __init__() 的继承属性?
How to slightly modify an inherited attribute from parent __init__() with minimal changes in the child class in Python?
代码如下:
def some_function1():
pass
def some_function2():
pass
def some_function3():
pass
def some_function4():
pass
class ReporterClass():
def __init__(self, data_reporter):
self.data_reporter = data_reporter
class ParentClass():
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
self.datacollector = ReporterClass(data_reporter={
'Report info 1': some_function1,
'Report info 2': some_function2,
'Report info 3': some_function3,
})
class ChildClass(ParentClass):
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
self.datacollector = ReporterClass(data_reporter={
'Report info 1': some_function1,
'Report info 2': some_function2,
'Report info 3': some_function3,
'Report info 4': some_function4,
})
这在这个玩具示例中工作正常,但我在实际代码中遇到的问题是 __init__()
中有很多参数,例如 param1
... param100
.同样,data_reporter
中有许多字典项,例如 Report info 1
... Report info 100
。我喜欢通过将 'Report info 4': some_function4
添加到 ChildClass
中的 self.datacollector
来简单地进行修改,而不必完全覆盖 parent 的 __init__()
并且不必重复所有参数代码。任何提示或建议将不胜感激。
--- 编辑 ---
再详细解释一下。根据建议,我会将 child class 创建为 ChildClass1
。但是,我的class在初始化的时候有很多参数。不仅需要全部写在childclass'__init__()
,还需要"repeat"写在super().__init__()
。所以想知道有没有更方便更优雅的方法,不用再赘述了。类似于 ChildClass2
?
class ChildClass1(ParentClass):
def __init__(self,
param1,
param2,
., # Very long list of parameters
.,
.,
param100,
):
super().__init__(
param1,
param2,
., # Very long list of parameters
.,
.,
param100
)
self.datacollector.data_reporter['Report info 4'] = some_function4
class ChildClass2(ParentClass):
def __init__(self, *args):
some_var_to_store_parent_init_params = super().__init__.attr
for param in some_var_to_store_parent_init_params:
# somehow assign it back to ChildClass' args
super().__init__(some_var_to_store_parent_init_params)
self.datacollector.data_reporter['Report info 4'] = some_function4
假设我正确理解了您的问题,以下内容是否符合您的要求?
class MaybeWorks:
def __init__(self, num_funcs, *args):
for k, arg in enumerate(args):
setattr(self, 'param'+str(k+1), arg)
data_reporter=dict()
for k in range(num_funcs):
data_reporter['Report info '+str(k+1)] = globals()['some_function'+str(k+1)]
self.datacollector = ReporterClass(data_reporter)
调用super()__init__()
将帮助您很好地重用父__init__
;然后你可以在 ChildClass
的 'ReporterClass.datacollector' 属性中添加必要的附加功能
您可以进一步重构构建 ReporterClass.datacollector
的方式以使用参数填充它 - 相反,在这里,在调用 super()
.
之后直接添加其他值
def some_function1(): pass
def some_function2(): pass
def some_function3(): pass
def some_function4(): pass
class ReporterClass:
def __init__(self, data_reporter):
self.data_reporter = data_reporter
class ParentClass:
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
self._data_reporter = {'Report info 1': some_function1,
'Report info 2': some_function2,
'Report info 3': some_function3}
self.datacollector = ReporterClass(self._data_reporter)
class ChildClass(ParentClass):
def __init__(self, param1, param2):
super().__init__(param1, param2)
self.datacollector.data_reporter['Report info 4'] = some_function4
if __name__ == '__main__':
print(ParentClass(1, 2).datacollector.data_reporter)
print(ChildClass(3, 4).datacollector.data_reporter)
[编辑] ----------
如果您发现处理许多参数很麻烦,可以使用 args、kwargs,如下所示:
class ParentClass:
def __init__(self, *args):
self.param1, self.param2 = args
self._data_reporter = {'Report info 1': some_function1,
'Report info 2': some_function2,
'Report info 3': some_function3}
self.datacollector = ReporterClass(self._data_reporter)
class ChildClass(ParentClass):
def __init__(self, *args):
super().__init__(*args)
self.datacollector.data_reporter['Report info 4'] = some_function4
if __name__ == '__main__':
print(ParentClass(1, 2).datacollector.data_reporter)
print(ChildClass(3, 4).datacollector.data_reporter)
代码如下:
def some_function1():
pass
def some_function2():
pass
def some_function3():
pass
def some_function4():
pass
class ReporterClass():
def __init__(self, data_reporter):
self.data_reporter = data_reporter
class ParentClass():
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
self.datacollector = ReporterClass(data_reporter={
'Report info 1': some_function1,
'Report info 2': some_function2,
'Report info 3': some_function3,
})
class ChildClass(ParentClass):
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
self.datacollector = ReporterClass(data_reporter={
'Report info 1': some_function1,
'Report info 2': some_function2,
'Report info 3': some_function3,
'Report info 4': some_function4,
})
这在这个玩具示例中工作正常,但我在实际代码中遇到的问题是 __init__()
中有很多参数,例如 param1
... param100
.同样,data_reporter
中有许多字典项,例如 Report info 1
... Report info 100
。我喜欢通过将 'Report info 4': some_function4
添加到 ChildClass
中的 self.datacollector
来简单地进行修改,而不必完全覆盖 parent 的 __init__()
并且不必重复所有参数代码。任何提示或建议将不胜感激。
--- 编辑 ---
再详细解释一下。根据建议,我会将 child class 创建为 ChildClass1
。但是,我的class在初始化的时候有很多参数。不仅需要全部写在childclass'__init__()
,还需要"repeat"写在super().__init__()
。所以想知道有没有更方便更优雅的方法,不用再赘述了。类似于 ChildClass2
?
class ChildClass1(ParentClass):
def __init__(self,
param1,
param2,
., # Very long list of parameters
.,
.,
param100,
):
super().__init__(
param1,
param2,
., # Very long list of parameters
.,
.,
param100
)
self.datacollector.data_reporter['Report info 4'] = some_function4
class ChildClass2(ParentClass):
def __init__(self, *args):
some_var_to_store_parent_init_params = super().__init__.attr
for param in some_var_to_store_parent_init_params:
# somehow assign it back to ChildClass' args
super().__init__(some_var_to_store_parent_init_params)
self.datacollector.data_reporter['Report info 4'] = some_function4
假设我正确理解了您的问题,以下内容是否符合您的要求?
class MaybeWorks:
def __init__(self, num_funcs, *args):
for k, arg in enumerate(args):
setattr(self, 'param'+str(k+1), arg)
data_reporter=dict()
for k in range(num_funcs):
data_reporter['Report info '+str(k+1)] = globals()['some_function'+str(k+1)]
self.datacollector = ReporterClass(data_reporter)
调用super()__init__()
将帮助您很好地重用父__init__
;然后你可以在 ChildClass
您可以进一步重构构建 ReporterClass.datacollector
的方式以使用参数填充它 - 相反,在这里,在调用 super()
.
def some_function1(): pass
def some_function2(): pass
def some_function3(): pass
def some_function4(): pass
class ReporterClass:
def __init__(self, data_reporter):
self.data_reporter = data_reporter
class ParentClass:
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
self._data_reporter = {'Report info 1': some_function1,
'Report info 2': some_function2,
'Report info 3': some_function3}
self.datacollector = ReporterClass(self._data_reporter)
class ChildClass(ParentClass):
def __init__(self, param1, param2):
super().__init__(param1, param2)
self.datacollector.data_reporter['Report info 4'] = some_function4
if __name__ == '__main__':
print(ParentClass(1, 2).datacollector.data_reporter)
print(ChildClass(3, 4).datacollector.data_reporter)
[编辑] ----------
如果您发现处理许多参数很麻烦,可以使用 args、kwargs,如下所示:
class ParentClass:
def __init__(self, *args):
self.param1, self.param2 = args
self._data_reporter = {'Report info 1': some_function1,
'Report info 2': some_function2,
'Report info 3': some_function3}
self.datacollector = ReporterClass(self._data_reporter)
class ChildClass(ParentClass):
def __init__(self, *args):
super().__init__(*args)
self.datacollector.data_reporter['Report info 4'] = some_function4
if __name__ == '__main__':
print(ParentClass(1, 2).datacollector.data_reporter)
print(ChildClass(3, 4).datacollector.data_reporter)