2010-07-31 14 views
1

Je trouve utile de créer des "fonctions d'usine de méthode" qui enveloppent un attribut d'objet paramétré dans une certaine logique.méthodes usines qui prennent les attributs de classe en tant que paramètres

Par exemple:

"""Fishing for answers. 

>>> one().number_fisher() 
'one fish' 
>>> one().colour_fisher() 
'red fish' 
>>> two().number_fisher() 
'two fish' 
>>> two().colour_fisher() 
'blue fish' 
""" 


class one(object): 
    def number(self): 
     return 'one' 
    def colour(self): 
     return 'red' 
    def _make_fisher(sea): 
     def fisher(self): 
      return '{0} fish'.format(getattr(self, sea)()) 
     return fisher 
    number_fisher = _make_fisher('number') 
    colour_fisher = _make_fisher('colour') 

class two(one): 
    def number(self): 
     return 'two' 
    def colour(self): 
     return 'blue' 

Est-il nécessaire de passer l'attribut à make_fisher comme une chaîne, ou est-il une meilleure façon de le faire?

Si je transmets et que j'utilise un attribut réel, cela va briser le polymorphisme, puisque les instances de two utiliseront toujours la même référence pour l'objet attribut.

I.E.

diff --git a/fishery.py b/fishery.py 
index 840e85d..b98cf72 100644 
--- a/fishery.py 
+++ b/fishery.py 
@@ -4,10 +4,12 @@ 
'one fish' 
>>> one().colour_fisher() 
'red fish' 
+ 
+This version does not implement polymorphism, and so this happens: 
>>> two().number_fisher() 
-'two fish' 
+'one fish' 
>>> two().colour_fisher() 
-'blue fish' 
+'red fish' 
""" 


@@ -18,10 +20,10 @@ class one(object): 
     return 'red' 
    def _make_fisher(sea): 
     def fisher(self): 
-   return '{0} fish'.format(getattr(self, sea)()) 
+   return '{0} fish'.format(sea(self)) 
     return fisher 
- number_fisher = _make_fisher('number') 
- colour_fisher = _make_fisher('colour') 
+ number_fisher = _make_fisher(number) 
+ colour_fisher = _make_fisher(colour) 

class two(one): 
    def number(self): 

Il semble un peu faible d'avoir à utiliser une chaîne pour référencer l'attribut, mais je ne vois pas une autre façon de le faire. Y a-t-il?

Répondre

2

"Encore un niveau d'indirection" (parfois proposé comme la panacée magique de la programmation ;-) - tout comme pour les décorateurs typiques comme property. Par exemple .:

def makefisher(fun): 
    def fisher(self): 
    return '{0} fish'.format(fun(self)) 
    return fisher 

class one(object): 
    def number(self): return self._number() 
    def _number(self): return 'one' 
    number_fisher = makefisher(number) 

class two(one): 
    def _number(self): return 'two' 

Fondamentalement, la fonction enveloppe est la « fonction d'organisation » dans une variante particulièrement simple du modèle Méthode DP, et celle que vous prioritaire est la fonction « décroché » dans le même DP. Ou au moins, c'est une façon de le regarder, l'autre étant le "niveau d'indirection supplémentaire" que j'ai commencé avec ;-).