将类属性作为参数的方法工厂

时间:2010-07-31 05:56:23

标签: python polymorphism factory-method

我发现创建“方法工厂函数”非常有用,它可以在某些逻辑中包含参数化对象属性。

例如:

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

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

必须使用字符串来引用属性似乎有点弱,但我没有看到另一种方法来执行此操作。有吗?

1 个答案:

答案 0 :(得分:2)

“另一个层次的间接”(有时被提议为编程的神奇灵丹妙药;-) - 就像property这样的典型装饰者一样。 E.g:

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