1

クラスを継承し、基本クラスから継承されたメソッドを上書きしました。しかし、問題は、最初に宣言されたメソッドを呼び出すことによってバイパスしたい例外を中間メソッドが作成することです。2 番目の呼び出しを無視するようにmroに指定する方法はありますか?

例は次のとおりです。

class Base(object):
     def __init__(self):
         res = "Want this"
         print res

class BaseA(Base):
      def __init__(self):
          res = super(BaseA, self).__init__()
          res = "Not this"
          print res

class BaseB(BaseA):
      def __init__(self):
          res = super(BaseB, self).__init()
          #At this poing res is "Not this"
          #The desire is that it would be "Want this"
          print res

どうもありがとう

PD: クラス BaseB(Base, BaseA) のようなものが機能しますか?

4

3 に答える 3

6

通常、代わりにそのメソッドを修正します。

ただし、 の最初の引数は、からsuper()次のメソッドを探し始める場所です。通常は現在のクラスですが、基本クラスを渡すこともできます。

class BaseB(BaseA):
    def __init__(self):
        res = super(BaseA, self).__init__()

ここで、super()の MRO を取得し、その MRO をtype(self)見つけBaseAて、 を実装する次のクラスを探します__init__

問題のあるメソッドをバイパスする別の__init__方法は、バインドされていないメソッドをBase直接呼び出すことです。

class BaseB(BaseA):
    def __init__(self):
        res = Base.__init__(self)

MRO 検索を完全にバイパスします。

于 2014-02-25T19:26:21.887 に答える
2

これを修正する正しい方法は、改善された実装で問題のあるメソッドをオーバーライドする新しいクラス階層を作成することです。ただし、ハッカーに固執する場合は、これが必要な場合があります。

class BaseB(BaseA):
      def __init__(self):
          res = super(BaseA, self).__init()
          #At this poing res is "Not this"
          #The desire is that it would be "Want this"
          print res

BaseA に関してスーパー実装を求めていることに注意してください。つまり、BaseA 実装は使用されません。


ただし、ダイヤモンドの継承が関係している場合、これは間違ったことをする可能性があります。検討:

class Base(object):
    def __init__(self):
        print 'initing Base'

class BaseA(Base):
    def __init__(self):
        print 'initing BaseA'
        res = super(BaseA, self).__init__()

class BaseB(BaseA):
    def __init__(self):
        print 'initing BaseB'
        res = super(BaseA, self).__init__()

class BaseC(BaseA):
    def __init__(self):
        print 'initing BaseC'
        res = super(BaseC, self).__init__()

class BaseD(BaseB, BaseC):
    def __init__(self):
        print 'initing BaseD'
        res = super(BaseD, self).__init__()

print BaseD()

出力は次のとおりです。

initing BaseD
initing BaseB
initing Base
<__main__.BaseD object at 0x7f1e693a0110>

BaseCそれは私たちが望んでいたものではありませんが、スキップされました。これは、メソッド解決順序でとのBaseC間にあるためです。BaseBBaseABaseBBaseABaseC

>>> print [cls.__name__ for cls in BaseD.mro()]
['BaseD', 'BaseB', 'BaseC', 'BaseA', 'Base', 'object']
于 2014-02-25T19:29:57.547 に答える
0

どうですか

Base.__init__(self)

于 2014-02-25T19:29:44.637 に答える