2009-09-24 7 views
1

Je veux avoir une classe Python qui agit comme un wrapper pour une autre classe Python.Faire une façade en Python 2.5

Quelque chose comme ça

class xxx: 
    name = property(fset=lambda self, v: setattr(self.inner, 'name', v), fget=lambda self: getattr(self.inner, 'name')) 

    def setWrapper(self, obj) 
     self.inner = obj 

Alors, quand quelqu'un dit xxx(). X = 'bonjour' Je le veux pour définir la valeur sur xxx(). Inner.whatever et non xxx(). X.

Est-ce possible? J'ai essayé lambdas, mais en vain. J'utilise Python 2.5

Edit: Maintenant, ma femme ne me précipitait au lit pour que je puisse débusquer le code un peu plus. J'avais une idée de ce que vous aviez en dessous, mais du docs, il semblait que vous deviez éviter de surcharger __setattr__/__getattr__ et utiliser la propriété à la place. Si ce n'est pas possible de le faire via la fonction de propriété, alors je vais utiliser le __setattr__/__getattr__? Merci

Répondre

6

C'est ici que vous utilisez les méthodes __setattr__ et __getattr__ telles que documentées here.

En bref, si vous faites ceci:

class Wrapper(object): 
    def __init__(self, wrapped): 
     object.__setattr__(self, 'inner', wrapped) 

    def __getattr__(self, attr): 
     return getattr(self.inner, attr) 

    def __setattr__(self, attr, value): 
     setattr(self.inner, attr, value) 

Il faut faire ce que vous êtes après. Je recommande fortement de lire les documents liés à ci-dessus.

EDIT: Comme indiqué, la version d'origine échoue en raison de __setattr__ étant appelé sans condition. J'ai mis à jour cet exemple. Notez que cette version dépend du comportement de classe de nouveau style (comme indiqué par le sous-classement de l'objet). Pour style ancien, je pense que vous auriez besoin de jouer avec __dict__ comme suit:

class OldStyleWrapper: 
    def __init__(self, wrapped): 
     self.__dict__['inner'] = wrapped 

    def __getattr__(self, attr): 
     return getattr(self.inner, attr) 

    def __setattr__(self, attr, value): 
     setattr(self.inner, attr, value) 
5

Comme une autre réponse dit, __getattr__ et __setattr__ sont la clé, mais vous avez besoin de soins lorsque vous utilisez ce dernier ...:

class Wrapper(object): 
    def __init__(self, wrapped): 
     object.__setattr__(self, 'inner', wrapped) 

    def __getattr__(self, n): 
     return getattr(self.inner, n) 

    def __setattr__(self, n, value): 
     setattr(self.inner, n, value) 

Vous n'avez pas besoin de précautions pour self.inneraccès, parce que __getattr__ est appelé uniquement pour les attributs qui ne sont pas par ailleurs présents; mais __setattr__ est appelée pour tous les attributs, alors quand vous avez réellement besoin misself.inner (ou tout autre attribut), vous devez contourner explicitement __setattr__ (ici j'utilise object dans le but, donc je aussi Hériter de object - fortement recommandé de toute façon, en Python 2. *, sinon vous feriez une "classe à l'ancienne" [[le type qui A disparu dans Python 3]], que vous ne voulez vraiment pas. .. ;-).

+0

Bon point, je l'ai édité mon exemple pour correspondre à la vôtre. =) – Benno

0

Je crois que les deux Alex et les réponses de Ben devraient modifier leur appel setattr comme suit:

setattr(self.inner, n, value) 
Questions connexes