質問

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

例としては次のようなものが考えられます。

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)のようなものは機能するでしょうか?

役に立ちましたか?

解決

通常は代わりにその方法を修正します。

しかし、super()の最初の引数は、から次の方法の検索を開始する場所です。通常、それは現在のクラスですが、基本クラスを渡すこともできます。

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

ここでは、super()type(self)のMROを取り、そのMROのBaseAを見つけ、次のクラスを実装します。

問題のある__init__メソッドをバイパスするもう1つの方法は、__init__で直接の未結合メソッドを呼び出すだけです。

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

すべてのMRO検索を完全に迂回します。

他のヒント

これを修正する正しい方法は、改善された実装で問題のある方法をオーバーライドする新しいクラス階層を作成することです。あなたがハッキーを主張した場合、これはあなたが望むものかもしれません:

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
.

基礎に関する超実装を求めることに注意してください。これは、基本実装が決して使用されないことを意味します。


しかし、このは、ダイヤモンドの継承が関与しているときに間違ったことを行うことができます。検討してください:

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とメソッドの解像度の順序でBaseBBaseAの間に起こるため、BaseBからBaseAにスキップされると、誤ってBaseCが無視されます。

>>> print [cls.__name__ for cls in BaseD.mro()]
['BaseD', 'BaseB', 'BaseC', 'BaseA', 'Base', 'object']
.

どうだろう

Base.__init__(self)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top