2017-12-05 19 views
10

に私が読んでいるレイモンドヘッティンガーのPython’s super() considered super!、この例がありますでページについて:を呼び出す `スーパー()`親クラス

class Shape: 
    def __init__(self, shapename, **kwds): 
     self.shapename = shapename 
     super().__init__(**kwds)   

class ColoredShape(Shape): 
    def __init__(self, color, **kwds): 
     self.color = color 
     super().__init__(**kwds) 

cs = ColoredShape(color='red', shapename='circle') 

なぜそれがここShapesuper()を呼び出す必要がありますか?私は、から暗黙的に継承しているので、object.__init__(**kwds)Shapeから呼び出していることを理解しています。

はしても、その文なしに、我々はすでに親の__init__ですでにshapenameを確立

  • は親の__init__とを呼び出した後、
  • 、子クラスのcolor明示的なメソッドのオーバーライド内を設立しましたsuper()ColoredShape

私の知る限り、この行をドロップすると、同じ動作&機能を生成します。

class Shape: # (object) 
    def __init__(self, shapename, **kwds): 
     self.shapename = shapename 
     # super().__init__(**kwds) 

class ColoredShape(Shape): 
    def __init__(self, color, **kwds): 
     self.color = color 
     super().__init__(**kwds) 
    def check(self): 
     print(self.color) 
     print(self.shapename) 

cs = ColoredShape(color='red', shapename='circle') 

cs.check() 
# red 
# circle 

ここShapesuper()の目的は何ですが?

+0

私は、 '** kwds'を使ってあるクラスから他のクラスに引数を送って' ** kwds'から 'shapename'を取り除く方法のほんの一例だと思う - このシェイプの親は重要ではありません。たぶん 'Shape'は親を持つべきですが、すべての例では主要素ではありません。 – furas

答えて

5

@ user2357112はすでに正しい答えを提供しています。私は、私がここを去るつもりはあるが、user2357112が説明しているものとほとんど同じだから、私がやりたいと思っていた事例に取り組んでいた。このようにミックスインクラスを考えてみましょう:

myshape = ColoredShape('red', shapename='circle', x=1, y=1) 
print(myshape.x, myshape.y) 
:あなたがこれを行うとき

class ColoredShape(Shape, PositionMixin): 
    def __init__(self, color, **kwds): 
     self.color = color 
     super().__init__(**kwds) 

Shape場合は、その後、super.__init__を呼び出すことはありません。

class PositionMixin: 
    def __init__(self, x=0, y=0, **kwds): 
     super().__init__(**kwds) 
     self.x = x 
     self.y = y 

するのは、あなたのColoredShapeクラスにすることを適用するとしましょう

あなたは:

Traceback (most recent call last): 
    File "supertest.py", line 18, in <module> 
    print (myshape.x, myshape.y) 
AttributeError: 'ColoredShape' object has no attribute 'x' 

を呼び出すには、PositionMixin__init__メソッドを呼び出す必要があります。

+0

[diamond rule](https://docs.python.org/3/whatsnew/2.2.html#multiple-inheritance-the-diamond-rule)を読んでいただきありがとうございます。なぜ 'shape'の' super().__ init __() 'が' object'(親) '__init __()'ではなく 'PositionMixin'(兄弟)を参照するのを知っているのか簡単に説明できますか?あるいは、私はこれをそのまま受けて、私がMROを全くよく知らないことを認めなければなりませんか? –

+0

私はあなたのために良い答えがありません。つまり、「Shape」は何も知りません。 'super()'を呼び出すと、MROの上位の適切なクラスを指すプロキシオブジェクトが返され、 'Shape'がその上で動作しています。しかし、これはちょっと波打っていて、Pythonオブジェクトがより良い答えを提供するためにどのように構築されているかについての詳細はわかりません。 – larsks

7

ポイントは協調的な複数継承です。記事全体のポイントは、実際には協調的な複数の継承です。

Shapeを参照してください。object以外の保護者は表示されません。確かに、それはShapeの後にMROに兄弟や他の何もないことを意味するものではありません。 super()はスーパークラスだけではありません。 method resolution orderのメソッドの次の実装を検索します。たとえば、記事の後のクラスの一つが、この場合、

class MovableColoredShape(ColoredShape, MoveableAdapter): 
    pass 

で、Shape.__init__super().__init__、またはMoveableAdapter.__init__を呼び出す必要があると、すべてさらに__init__呼び出しはスキップされます。

関連する問題