2

メタクラスを使用して次の機能を実装しようとしています:

class foo( object ):

    def __init__( self ):
        self.val = 'foo'

    def bar( self ):
        print 'hello world'
        print self.val

f = foo()
f.bar() #prints 'hello world' followed by foo

def newbar( self ):
    super( **?**, self).bar()
    print 'another world!'

fooNew = type('fooNew', (foo,), {'bar':newbar})
n = fooNew()
n.bar() # should print everything in f.bar() followed by 'another world!'

モンキー パッチを使用して、独自の関数 newbar を実装できることを理解しています。ただし、微妙な違いがあります。新しい bar 関数では、最初に基本クラスの bar 関数を実行してから、追加機能を実行する必要があります。

これどうやってするの?またはどうすればこれを改善できますか?

4

2 に答える 2

5

を使用super()して基底クラス メソッドを呼び出すと、特定の多重継承の状況では利点がありますが、他のほとんどの場合 (つまり、95% のユース ケース) では欠点があります。したがってsuper()、ここでは単純に使用せず、基本クラスのメソッドを直接呼び出してください。

私はさらに別の方法に進みます(クラスを動的に作成したいと確信している場合)。関数内でクラス全体を定義して返すことができます。

def class_factory():
    class NewFoo(foo):
        def bar(self):
            foo.bar()
            print 'another world!'
    return NewFoo
于 2012-09-13T22:32:10.827 に答える
3

の定義を変更して、newbar代わりに関数を返すことができます。

def newbar_factory(cls):
    def newbar(self):
        super(cls, self).bar()
        # Alternately, as Sven points out you could do
        # cls.bar(self)
        print "another world!"

    return newbar

# Use
fooNew = type('fooNew', (foo,), {'bar':newbar_factory(foo)})

あなたがやろうとしているようなことを達成するためのより良い方法がおそらくありますが、これはトリックを行うはずです.

于 2012-09-13T22:31:29.260 に答える