我有一个类有一些回调和它自己的接口,类似于:
class Service:
def __init__(self):
connect("service_resolved", self.service_resolved)
def service_resolved(self, a,b c):
''' This function is called when it's triggered
service resolved signal and has a lot of parameters'''
connect函数是例如gtkwidget.connect,但我希望这个连接更通用,所以我决定使用“扭曲的”方法:
class MyService(Service):
def my_on_service_resolved(self, little_param):
''' it's a decorated version of srvice_resolved '''
def service_resolved(self,a,b,c):
super(MyService,self).service_resolved(a,b,c)
little_param = "something that's obtained from a,b,c"
self.my_on_service_resolved(little_param)
所以我可以通过覆盖my_on_service_resolved来使用MyService。
问题是“属性”污染。在实际实现中,Service有一些属性可以在MyService和MyService子类中被意外覆盖。
如何避免属性污染?
我认为这是一种“包装”方式,但我不知道这是否是一个很好的解决方案:
class WrapperService():
def __init__(self):
self._service = service_resolved
# how to override self._service.service_resolved callback?
def my_on_service_resolved(self,param):
'''
'''
答案 0 :(得分:3)
避免与派生类的意外冲突是存在“双引导下划线”命名方法的原因:如果在类Service
__foo
中命名属性,Python编译器将在内部“破坏”该名称为_Service__foo
,不太可能发生意外冲突。唉,并非不可能:子类可能也被命名为Service
(并且存在于另一个模块中),而也具有自己的__foo
属性。这将被命名为完全相同的方式,导致再次发生冲突。改进包括命名基类BaseService
等,利用派生类不太可能被命名为Base
的事实。但是,最后,除了明确记录这样的约定之外别无选择(至少如果子类将由具有很少Python经验的程序员编写)。
我不认为“意外冲突”问题足以迫使你完全放弃子类化(赞成使用独家包装),这基本上是避免意外名称冲突的唯一方法某些。你称之为“扭曲式”的方法(实际上是模板方法设计模式的一种情况)是非常可行的,在现实生活中,命名和文档设计选择的混合证明足以避免它的“冲突”风险。