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

发布于 2024-09-12 09:52:51 字数 1788 浏览 2 评论 0原文

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

例如:

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

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

I'm finding it useful to create "method factory functions" that wrap a parametrized object attribute in some logic.

For example:

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

Is it necessary to pass the attribute to make_fisher as a string, or is there a better way to do this?

If I pass and use an actual attribute, this will break polymorphism, since instances of two will still be using that same reference to the attribute object.

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

It seems a bit weak to have to use a string to reference the attribute, but I'm not seeing another way to do this. Is there?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小瓶盖 2024-09-19 09:52:51

“多一层间接性”(有时被认为是编程的灵丹妙药;-)——就像像 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 中的“挂钩函数”。或者至少,这是看待它的一种方式,另一种是我一开始使用的“额外的间接级别”;-)。

"One more level of indirection" (sometimes proposed as programming's magic panacea;-) -- just like for typical decorators like 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'

Basically, the function you wrap is the "organizing function" in a peculiarly simple variant of the Template Method DP, and the one you override is the "hook function" in that same DP. Or at least, that's one way to look at it, the other being the "extra level of indirection" one I started out with;-).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文