在多个 children 中覆盖 parent 函数
Overwriting parent function in multiple children
我有几个 child class 我想使用,但它们都从它们的 parent 继承了一个方法,但它的行为并不符合我的需要到.
class ParentClass():
def __init__(self, value):
self.value = value
def annoying_funct(self):
print("I don't do quite what's needed and print {0}".format(self.value + 1))
def other_parent(self):
print("I do other useful things my children inherit")
class Child1(ParentClass):
def __init__(self, value, new_value1):
super(Child1, self).__init__(value)
self.new_value1 = new_value1
def other_child1(self):
print("I do useful child things")
class Child2(ParentClass):
def __init__(self, value, new_value2):
super(Child2, self).__init__(value)
self.new_value2 = new_value2
def other_child2(self):
print("I do other useful child things")
我想像这样覆盖 annoying_funct()
:
def annoying_funct():
print("I behave the way I am needed to and print {0}".format(self.value))
ParentClass
、Child1
和 Child2
来自一个非常复杂的库 (scikit-learn
),因此我想使所有包装器尽可能薄。在根据需要更改 parent class 的同时获得我的两个 child class 的功能的 cleanest/most pythonic 方式是什么?
到目前为止我的想法:
创建一个继承自 parent 的新 class,它会覆盖我不喜欢的函数,然后为 children 制作包装器 classes继承自新的 class 和 child classes.
class NewParentClass(ParentClass):
def annoying_funct(self):
print("I behave the way I am needed to and print {0}".format(self.value))
class NewChild1(NewParentClass, Child1):
pass
class NewChild2(NewParentClass, Child2):
pass
我的困惑领域:
- 这是正确的方法吗?这似乎有点奇怪和笨拙。有更简洁的方法吗?
- 这两个 child class 使用的语法是否正确?它为我运行,但让他们只继承和传递似乎有点奇怪。
- 让我的新 parent 继承以前的 parent 是正确的做法吗?代码为 children 运行,没有
parentClass
和 newParentClass
之间的继承(例如 def newParentClass():
),但是如果有人试图创建 newParentClass()
的实例该函数不起作用,因为它使用了 class (value
) 中不存在的属性。如果我假设永远不会使用 class 可以吗?
有几种方法可以满足您的要求。
- 创建一个新的 class 从父 class 继承,然后将其用作新的父 class。
此解决方案的唯一缺点是,当您将新的父项或子项 class 提供给需要原始父项 class 的函数时,可能无法正常工作,因为它们可能会使用 annoying_funct
并依赖于烦人的行为。
class NewParentClass:
def annoying_funct(self):
print("I behave the way I am needed to and print {0}".format(self.value))
class NewChild1(NewParentClass):
pass
class NewChild2(NewParentClass):
pass
- 操纵现有父级class
这是我想使用的解决方案,因为它通过用一个表现良好的替代它来完全破坏 annoying_funct
,再次购买,其他需要前者 annoying_funct
的方法和功能可能会失败.好的一面是,您不需要创建另一个父项 class 和子项,因此您的代码会更加优雅。
class ParentClass():
...
def annoying_funct(self):
print("I don't do quite what's needed and print {0}".format(self.value + 1))
...
def well_behaving_func(s):
print("Good")
# Dynamically change the class method
ParentClass.annoying_func = well_behaving_func
class Child1(Parent):
pass
class Child2(Parent):
pass
c = Child1()
c.annoying_funct() # prints 'Good'
- 在从父 class 继承之前添加一个行为良好的新方法。
如果您想保持当前的行为并且不希望依赖父 class 的现有代码或包中断,您当然不应该覆盖父 [=] 中的 annoying_funct
37=]。所以你应该定义一个行为良好的函数并在子 classes.
中使用它
class ParentClass():
...
def annoying_funct(self):
print("I don't do quite what's needed and print {0}".format(self.value + 1))
...
def well_behaving_func(s):
print("Good")
# Dynamically change the class method
ParentClass.well_behaving_func = well_behaving_func
class Child1(Parent):
pass
class Child2(Parent):
pass
c = Child1()
# use 'well_behaving_func', not the annoying one
c.well_behaving_func() # prints 'Good'
我最终做的是使用 mixin 的概念将我的新功能添加到子 classes。结果代码如下:
class AnnoyMixin:
def well_behaving_func(self):
print("I behave the way I am needed to and print {0}".format(self.value))
class NewChild1(AnnoyMixin, Child1):
def annoying_funct(self):
return well_behaving_func(self)
class NewChild2(AnnoyMixin, Child2):
def annoying_funct(self):
return well_behaving_func(self)
在功能上,这与我在问题中提出的代码的行为基本相同,但修改有助于提高可读性。首先,通过将新父级命名为 "Mixin",可以清楚地表明此 class 并非设计用于独立存在,而是旨在向另一个 class 添加功能。因此,AnnoyMixin
不需要从 ParentClass
继承,简化了 NewChild
class 的继承。
其次,我们创建了新函数 well_behaving_func
,而不是覆盖 AnnoyMixin
中的 annoying_funct
。然后是 NewChild
classes 作业通过调用 well_behaving_func
覆盖 annoying_funct
。从功能上讲,这与 AnnoyMixin
已覆盖 annoying_funct
的工作方式大致相同,但通过这种方式,阅读代码的人会更清楚 annoying_funct
在 NewChild
classes.
我有几个 child class 我想使用,但它们都从它们的 parent 继承了一个方法,但它的行为并不符合我的需要到.
class ParentClass():
def __init__(self, value):
self.value = value
def annoying_funct(self):
print("I don't do quite what's needed and print {0}".format(self.value + 1))
def other_parent(self):
print("I do other useful things my children inherit")
class Child1(ParentClass):
def __init__(self, value, new_value1):
super(Child1, self).__init__(value)
self.new_value1 = new_value1
def other_child1(self):
print("I do useful child things")
class Child2(ParentClass):
def __init__(self, value, new_value2):
super(Child2, self).__init__(value)
self.new_value2 = new_value2
def other_child2(self):
print("I do other useful child things")
我想像这样覆盖 annoying_funct()
:
def annoying_funct():
print("I behave the way I am needed to and print {0}".format(self.value))
ParentClass
、Child1
和 Child2
来自一个非常复杂的库 (scikit-learn
),因此我想使所有包装器尽可能薄。在根据需要更改 parent class 的同时获得我的两个 child class 的功能的 cleanest/most pythonic 方式是什么?
到目前为止我的想法:
创建一个继承自 parent 的新 class,它会覆盖我不喜欢的函数,然后为 children 制作包装器 classes继承自新的 class 和 child classes.
class NewParentClass(ParentClass):
def annoying_funct(self):
print("I behave the way I am needed to and print {0}".format(self.value))
class NewChild1(NewParentClass, Child1):
pass
class NewChild2(NewParentClass, Child2):
pass
我的困惑领域:
- 这是正确的方法吗?这似乎有点奇怪和笨拙。有更简洁的方法吗?
- 这两个 child class 使用的语法是否正确?它为我运行,但让他们只继承和传递似乎有点奇怪。
- 让我的新 parent 继承以前的 parent 是正确的做法吗?代码为 children 运行,没有
parentClass
和newParentClass
之间的继承(例如def newParentClass():
),但是如果有人试图创建newParentClass()
的实例该函数不起作用,因为它使用了 class (value
) 中不存在的属性。如果我假设永远不会使用 class 可以吗?
有几种方法可以满足您的要求。
- 创建一个新的 class 从父 class 继承,然后将其用作新的父 class。
此解决方案的唯一缺点是,当您将新的父项或子项 class 提供给需要原始父项 class 的函数时,可能无法正常工作,因为它们可能会使用 annoying_funct
并依赖于烦人的行为。
class NewParentClass:
def annoying_funct(self):
print("I behave the way I am needed to and print {0}".format(self.value))
class NewChild1(NewParentClass):
pass
class NewChild2(NewParentClass):
pass
- 操纵现有父级class
这是我想使用的解决方案,因为它通过用一个表现良好的替代它来完全破坏 annoying_funct
,再次购买,其他需要前者 annoying_funct
的方法和功能可能会失败.好的一面是,您不需要创建另一个父项 class 和子项,因此您的代码会更加优雅。
class ParentClass():
...
def annoying_funct(self):
print("I don't do quite what's needed and print {0}".format(self.value + 1))
...
def well_behaving_func(s):
print("Good")
# Dynamically change the class method
ParentClass.annoying_func = well_behaving_func
class Child1(Parent):
pass
class Child2(Parent):
pass
c = Child1()
c.annoying_funct() # prints 'Good'
- 在从父 class 继承之前添加一个行为良好的新方法。
如果您想保持当前的行为并且不希望依赖父 class 的现有代码或包中断,您当然不应该覆盖父 [=] 中的 annoying_funct
37=]。所以你应该定义一个行为良好的函数并在子 classes.
class ParentClass():
...
def annoying_funct(self):
print("I don't do quite what's needed and print {0}".format(self.value + 1))
...
def well_behaving_func(s):
print("Good")
# Dynamically change the class method
ParentClass.well_behaving_func = well_behaving_func
class Child1(Parent):
pass
class Child2(Parent):
pass
c = Child1()
# use 'well_behaving_func', not the annoying one
c.well_behaving_func() # prints 'Good'
我最终做的是使用 mixin 的概念将我的新功能添加到子 classes。结果代码如下:
class AnnoyMixin:
def well_behaving_func(self):
print("I behave the way I am needed to and print {0}".format(self.value))
class NewChild1(AnnoyMixin, Child1):
def annoying_funct(self):
return well_behaving_func(self)
class NewChild2(AnnoyMixin, Child2):
def annoying_funct(self):
return well_behaving_func(self)
在功能上,这与我在问题中提出的代码的行为基本相同,但修改有助于提高可读性。首先,通过将新父级命名为 "Mixin",可以清楚地表明此 class 并非设计用于独立存在,而是旨在向另一个 class 添加功能。因此,AnnoyMixin
不需要从 ParentClass
继承,简化了 NewChild
class 的继承。
其次,我们创建了新函数 well_behaving_func
,而不是覆盖 AnnoyMixin
中的 annoying_funct
。然后是 NewChild
classes 作业通过调用 well_behaving_func
覆盖 annoying_funct
。从功能上讲,这与 AnnoyMixin
已覆盖 annoying_funct
的工作方式大致相同,但通过这种方式,阅读代码的人会更清楚 annoying_funct
在 NewChild
classes.