我发现创建“方法工厂函数”非常有用,它可以在某些逻辑中包含参数化对象属性。
例如:
"""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):
必须使用字符串来引用属性似乎有点弱,但我没有看到另一种方法来执行此操作。有吗?
答案 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中的“钩子函数”。或者至少,这是看待它的一种方式,另一种是我开始使用的“间接的额外水平”; - )。