93

私はいくつかのクラスをゲッターとセッターの広範な使用からプロパティのよりpythonicな使用に変更しています。

しかし、以前のゲッターまたはセッターの一部が基本クラスの対応するメソッドを呼び出してから、別のことを実行したため、今は行き詰まっています。しかし、これをプロパティでどのように達成できるのでしょうか? 親クラスでプロパティのゲッターまたはセッターを呼び出す方法は?

もちろん、属性自体を呼び出すだけで無限再帰が得られます。

class Foo(object):

    @property
    def bar(self):
        return 5

    @bar.setter
    def bar(self, a):
        print a

class FooBar(Foo):

    @property
    def bar(self):
        # return the same value
        # as in the base class
        return self.bar # --> recursion!

    @bar.setter
    def bar(self, c):
        # perform the same action
        # as in the base class
        self.bar = c    # --> recursion!
        # then do something else
        print 'something else'

fb = FooBar()
fb.bar = 7
4

7 に答える 7

111

プロパティによって呼び出される基本クラス関数を呼び出すことができると思うかもしれません。

class FooBar(Foo):

    @property
    def bar(self):
        # return the same value
        # as in the base class
        return Foo.bar(self)

これは試してみるべき最も明白なことだと思いますが、bar は呼び出し可能オブジェクトではなくプロパティであるため、機能しません。

しかし、プロパティは単なるオブジェクトであり、対応する属性を見つけるためのゲッター メソッドがあります。

class FooBar(Foo):

    @property
    def bar(self):
        # return the same value
        # as in the base class
        return Foo.bar.fget(self)
于 2009-06-20T11:51:38.787 に答える
63

super()トリックを行う必要があります:

return super().bar

Python 2.x では、より冗長な構文を使用する必要があります。

return super(FooBar, self).bar
于 2009-06-20T11:46:49.080 に答える
28

super基本クラス名を明示的に参照する必要のない別の方法があります。

基本クラス A:

class A(object):
    def __init__(self):
        self._prop = None

    @property
    def prop(self):
        return self._prop

    @prop.setter
    def prop(self, value):
        self._prop = value

class B(A):
    # we want to extend prop here
    pass

B で、親クラス A のプロパティ ゲッターにアクセスします。

他の人がすでに答えているように、それは次のとおりです。

super(B, self).prop

または Python 3 の場合:

super().prop

これは、ゲッター自体ではなく、プロパティのゲッターによって返される値を返しますが、ゲッターを拡張するには十分です。

B で、親クラス A のプロパティ セッターにアクセスします。

私がこれまでに見た中で最高の推奨事項は次のとおりです。

A.prop.fset(self, value)

私はこれがより良いと信じています:

super(B, self.__class__).prop.fset(self, value)

この例では、両方のオプションが同等ですが、super を使用すると、 の基本クラスから独立しているという利点がありBます。Bプロパティを拡張するクラスから継承する場合、のコードCを更新する必要はありません。B

A のプロパティを拡張する B の完全なコード:

class B(A):
    @property
    def prop(self):
        value = super(B, self).prop
        # do something with / modify value here
        return value

    @prop.setter
    def prop(self, value):
        # do something with / modify value here
        super(B, self.__class__).prop.fset(self, value)

1 つの警告:

プロパティにセッターがない場合を除き、セッターとゲッターBのうちの 1 つの動作のみを変更する場合でも、両方を定義する必要があります。

于 2016-06-06T17:14:41.853 に答える
4

試す

@property
def bar:
    return super(FooBar, self).bar

Python が基本クラス プロパティの呼び出しをサポートしているかどうかはわかりませんが。プロパティは実際には、指定された関数で設定され、クラス内のその名前を置き換える呼び出し可能なオブジェクトです。これは、利用可能なスーパー機能がないことを簡単に意味する可能性があります。

ただし、property() 関数を使用するようにいつでも構文を切り替えることができます。

class Foo(object):

    def _getbar(self):
        return 5

    def _setbar(self, a):
        print a

    bar = property(_getbar, _setbar)

class FooBar(Foo):

    def _getbar(self):
        # return the same value
        # as in the base class
        return super(FooBar, self)._getbar()

    def bar(self, c):
        super(FooBar, self)._setbar(c)
        print "Something else"

    bar = property(_getbar, _setbar)

fb = FooBar()
fb.bar = 7
于 2009-06-20T11:50:09.320 に答える
-4
    class Base(object):
      def method(self):
        print "Base method was called"

    class Derived(Base):
      def method(self):
        super(Derived,self).method()
        print "Derived method was called"

    d = Derived()
    d.method()

(つまり、あなたの説明から何かが欠けていない限り)

于 2009-06-20T11:51:44.030 に答える