2010-05-13 4 views
1

J'ai une classe qui a des callbacks et sa propre interface, quelque chose comme:callbacks prépondérants éviter la pollution de l'attribut

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

la fonction de connexion est par exemple le gtkwidget.connect, mais je veux que cette connexion est quelque chose de plus général, donc je l'ai décidé d'utiliser un « tordu comme » approche:

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) 

Je peux donc utiliser MyService en surchargeant my_on_service_resolved.

Le problème est la pollution "attributs". Dans l'implémentation réelle, Service a certains attributs qui peuvent accidentellement être remplacés dans MyService et ceux qui sous-classe MyService.

Comment puis-je éviter la pollution par attributs?

Ce que j'ai pensé est un « emballage » comme approche, mais je ne sais pas si c'est une bonne solution:

class WrapperService(): 
    def __init__(self): 
     self._service = service_resolved 
     # how to override self._service.service_resolved callback? 
    def my_on_service_resolved(self,param): 
     ''' 
     ''' 

Répondre

3

éviter des affrontements accidentels avec les classes dérivées est la raison pour laquelle la « double-garde soulignement "approche de nommage existe: si vous nommez un attribut dans la classe Service__foo, le compilateur Python va interne" mangle "ce nom à _Service__foo, ce qui rend improbable des conflits accidentels. Hélas, pas impossible: une sous-classe aussi sera nommée Service (et vivra dans un autre module) et aussi aura son propre attribut __foo ... qui serait nommé-maugréé exactement de la même manière, résultant en un conflit à nouveau. Les améliorations comprennent la dénomination des classes de base BaseService et similaires, en exploitant le fait qu'une classe dérivée est très peu susceptible d'être nommée Base. Mais, à la fin, il n'y a pas d'alternative à documenter clairement une convention comme celle-ci (du moins si les sous-classes vont être écrites par des programmeurs avec peu d'expérience Python).

Je ne pense pas que la question du « choc accidentel » est suffisant pour vous forcer à renoncer à sous-classement entièrement (en faveur de l'utilisation de l'emballage exclusivement), qui est essentiellement la seule façon d'éviter les conflits de noms accidentels pour certains. L'approche que vous appelez «twisted-like» (et qui est en fait un modèle de conception de Template Method) est tout à fait viable, et un mélange de conventions pour nommer et documenter vos choix de conception dans la pratique réelle s'avère suffisant pour éviter ses risques de "choc".