2010-05-13 2 views
1

У меня есть класс, который имеет некоторые функции обратный вызов и свой собственный интерфейс, что-то вроде:главенствующие обратные вызовов избегая загрязнения атрибутов

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''' 

функции подключаемой к примеру 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) 

так что я могу использовать MyService Переопределелив my_on_service_resolved.

Проблема - это «атрибуты» загрязнения. В реальной реализации служба имеет некоторые атрибуты, которые могут быть случайно переопределены в 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): 
     ''' 
     ''' 

ответ

3

избежать случайных столкновений с производными классами является причиной «двойной leading- подчёркивание ": если вы назовете атрибут в классе Service__foo, компилятор Python будет внутренне« калечить »это имя до _Service__foo, что делает случайные столкновения маловероятными. Увы, не невозможно: подкласс может также быть названным Service (и жить в другом модуле) и также имеет свой собственный атрибут __foo ... который был бы назван как искаженный точно так же, что привело бы к конфликту снова. Амелиорации включают в себя присвоение базовых классов BaseService и тому подобное, используя тот факт, что производный класс вряд ли будет называться Base. Но, в конце концов, нет никакой альтернативы четкому документированию такой конвенции (по крайней мере, если подклассы будут написаны программистами с небольшим опытом Python).

Я не думаю, что «случайное столкновение» вопрос достаточно, чтобы заставить вас отказаться от подклассов полностью (в пользу использования упаковки исключительно), которая в основном единственный способ избежать случайных конфликтов имен для определенного. Подход, который вы называете «скрученным» (и на самом деле является примером шаблона шаблона метода шаблонов), вполне жизнеспособен, а сочетание конвенции для наименования и документирования ваших вариантов дизайна в реальной практике доказывает достаточность, чтобы избежать его «столкновение» рисков.

Смежные вопросы