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仍将使用对属性对象的相同引用。

IE

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

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

4

1 回答 1

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 中的“钩子函数”。或者至少,这是看待它的一种方式,另一种是我开始使用的“额外间接级别”;-)。

于 2010-07-31T06:12:30.280 回答