фабрики метода, которые берут атрибуты класса в качестве параметров

Я нахожу, что это полезный для создания "фабрики метода функционирует", которые переносят параметрический атрибут объекта в некоторую логику.

Например:

"""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
задан intuited 31 July 2010 в 05:56
поделиться

1 ответ

«Еще один уровень косвенности» (иногда предлагается как волшебная панацея программирования ;-) - как и для типичных декораторов, таких как свойство . Например: [

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. Или, по крайней мере, это один способ взглянуть на это, а другой - «дополнительный уровень косвенности», с которого я начал ;-).

2
ответ дан 2 September 2019 в 22:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: