2010-07-31 77 views
1

我发现创建在某些逻辑中包装参数化对象属性的“方法工厂函数”很有用。将类属性作为参数的方法工厂

例如:

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

是有必要的属性make_fisher作为一个字符串传递,还是有更好的方法来做到这一点?

如果我传递并使用实际属性,则会破坏多态性,因为two的实例仍将对属性对象使用相同的引用。

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): 

似乎有点弱,不得不使用字符串引用属性,但我没有看到另一种方式来做到这一点。在那儿?

回答

2

“更多层次的间接性”(有时候被认为是编程的灵丹妙药;-) - 就像property这样的典型装饰者。例如: -

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' 

基本上,你包的功能是在模板方法DP的独有的简单变体“组织功能”,并且覆盖了一个在同一个DP的“钩子函数”。或者至少,这是看待它的一种方式,另一种是我开始使用的“间接性的额外级别”;-)。