3

これが私がやろうとしていることの要点です。オブジェクトのリストがあり、次のようなインスタンス メソッドがあることがわかっています。

def render(self, name, value, attrs)
   # Renders a widget...

オブジェクトのリストを反復処理しているため、実行時にこれらの関数を (本質的に) 装飾したいと考えています。そのため、レンダリング関数は次のようになります。

def render(self, name, value, attrs)
   self.attrs=attrs
   # Renders a widget...

2 つの注意事項:

  1. render 関数は django の一部です。ライブラリ内にデコレータを配置することはできません (できますが、この変更を維持して移行する必要があります)。
  2. インスタンスメソッドです。

ここに例があります: http://wiki.python.org/moin/PythonDecoratorLibrary

新しいインスタンス メソッドをクラスに追加する方法を示します。ここでの違いは、その attrs パラメーターを覚えた後で、元のメソッドにフォールスルーしたいということです。

4

2 に答える 2

7
def decorate_method(f):
  def wrapper(self, name, value, attrs):
    self.attrs = attrs
    return f(self, name, value, attrs)
  return wrapper

def decorate_class(c):
  for n in dir(c):
    f = getattr(c, n)
    if hasattr(f, 'im_func'):
      setattr(c, n, decorate_method(f.im_func))

別のシグニチャを持つメソッドをスキップするには、おそらく他のテストが必要になりますが、それとは別に、decorate_class(whatever)特定のクラスで必要なことを実行する必要がありますwhatever

于 2009-11-04T06:59:36.297 に答える
3

「古典的な」方法は、サブクラス化することです。このようにして、他の人々のクラスを台無しにする必要はありません。

class someclass(object):
    def render(self, name, value, attrs):
        print hasattr(self, 'attrs')

class my_render(object):
    def render(self, name, value, attrs):
        self.attrs = attrs # kind of decorating the function here
        return super(my_render, self).render(name, value, attrs)

class my_class(my_render, someclass): 
    pass    

someclass().render(1,2,3) # -> False
my_class().render(1,2,3) # -> True

MI の理由は、すべてのクラスが から継承できるためですmy_render。私はミックスインのコンセプトが好きです;-)

class my_otherclass(my_render, someotherclass): pass
class my_thirdclass(my_render, thirdclass): pass

# or less explicit
classlist = [ someclass, someotherclass ]
newclasses = [ type('my_'+cls.__name__, (my_render,cls), {}) for cls in classlist ]
于 2009-11-04T07:28:53.617 に答える