3

次の Python コードの「Self」オブジェクトがわかりません。

>>> class Ancestor( object ):
    def __init__( self ):
        self.name = "Ancestor"
    def getName( self ):
        return self.name


>>> class Base1( Ancestor ):
    def __init__( self ):
        self.name = "Base1"
        super( Base1, self ).__init__( )
    def getName( self ):
        return self.name


>>> class Base2( Base1 ):
    def __init__( self ):
        self.name = "Base2"
        super( Base2, self ).__init__( )
    def getName( self ):
        return self.name
    def getB1Name( self ):
        return super( Base2, self ).getName( )


>>> b2 = Base2( )
>>> b2.getName( )
'Ancestor'
>>> b2.getB1Name( )
'Ancestor'

結果が理解できません。b2.getName( ) の結果は「Base2」、b2.getB1Name( ) の結果は「Base1」になると予想していました。

4

2 に答える 2

4

関数を呼び出すと、super基本的にAncestorクラスのコンストラクターにジャンプし、そこでコードを実行します。コンストラクターで名前を に設定"Ancestor"し、基本クラスの新しい名前を上書きします。

各コンストラクターの最初の行を呼び出すとsuper、正しい名前が返されます。


ただし、 のgetB1Name関数B2は常に文字列を返すことに注意してください"Base2"name変数は単純に上書きされ、「シャドウ」されることはありません。

「シャドーイング」動作が保持されるように、自動的に名前マングリングを行うダブルアンダースコア変数を使用できますが、一般的には、よりクリーンな解決策は、単に異なる変数名を使用し、コードを設計して、同じ属性の 2 つの異なるバージョンが浮かんでいる必要はありません。

于 2013-09-16T18:47:56.827 に答える
3

selfクラスではなく、インスタンスを参照します。インスタンスは 1 つしかないため、 のすべての使用はself同じオブジェクトを参照します。このBase2.__init__オブジェクトに名前を設定します。次にsuperを呼び出すと、 が呼び出さBase1.__init__れ、同じオブジェクトに新しい名前が設定され、古い名前が上書きされます。

本当に必要な場合は、ダブルアンダースコア属性を使用して目的を達成できます。

于 2013-09-16T18:48:49.030 に答える