0

class BaseA(object):
    authors = ['a', 'b']
    author_list = authors

class BaseB(object):
    authors = ['a', 'b']

    def __init__(self, *arg, **kwargs):
        self.author_list = self.authors

class ChildA(BaseA):
    authors = ['c', 'd']

class ChildB(BaseB):
    authors = ['c', 'd']

child_a = ChildA()
child_b = ChildB()
print(child_a.author_list)
print(child_b.author_list)
>>> ['a', 'b']
>>> ['c', 'd']

コードの違いは何ですか?なぜ異なる結果が得られるのですか?

親のauthor_list属性がオーバーライドされない理由はとても混乱しています。

Pythonの継承の原則を教えてください。

4

4 に答える 4

4

ブロック内のマテリアルclassはクラス自体の一部であり、クラスを定義するときに1回実行されます。inのマテリアルはインスタンスごとであり、クラスをインスタンス化するたびに、インスタンス__init__ごとに1回実行されます。

最初の例(BaseA)では、クラス属性を作成してから、同じ値を指すauthors別の属性を作成します。author_listそれだ。他に何も起こりません。ChildAから継承するという事実は、再実行され BaseAません。終わって、一度定義されて完了しました。author_list = authorsauthor_listBaseA

2番目の例(BaseB)では、クラス属性を作成しますauthors。次に、__init__同じ値を指す新しいインスタンス属性を作成します。でこれを行う__init__ため、インスタンスごとに再実行されます。したがって、インスタンス化BaseBすると、新しい属性が取得されます。

child_aインスタンスとの属性をチェックしていることに注意してくださいchild_bChildA.author_listクラス(と)でそれらをチェックするとChildB.author_list、両方が同じ値()を持っていることがわかります['a', 'b']。ChildBでのアクションはで行われるため、__init__実際にクラスをインスタンス化した場合にのみ有効になります。

于 2013-01-12T08:09:09.530 に答える
0

違いは、2番目の例でauthor_listは、オブジェクトのインスタンスを作成するときに設定されることです。

クラスBaseAを定義するときはクラスメンバーを定義しますauthor_list。それで、インスタンスを作成するとChildA何も起こりませんauthor_list。継承されただけです。

定義するときBaseB、メンバーはありませんauthor_list。これは、のインスタンスが作成されるときにインスタンス変数として作成されますBaseB。したがって、ChildB同じことのインスタンスを作成すると発生しますが、authorsが再定義されるため、次の新しい値が使用されます。authors

于 2013-01-12T08:08:23.420 に答える
0

BaseB__init__関数では、親の作成者ではなく、子の作成者を呼び出しています。親の作者に電話をかけたい場合は、次のBaseB.authors代わりに使用しself.authorsます。

class BaseA(object):
    authors = ['a', 'b']
    author_list = authors

class BaseB(object):
    authors = ['a', 'b']

    def __init__(self, *arg, **kwargs):
        self.author_list = BaseB.authors

class ChildA(BaseA):
    authors = ['c', 'd']

class ChildB(BaseB):
    authors = ['c', 'd']

child_a = ChildA()
child_b = ChildB()
print(child_a.author_list)
print(child_b.author_list)
>>> ['a', 'b']
>>> ['a', 'b']

ParentBとChildBの作成者を連結する場合は、との両方を使用しBaseB.authorsますself.authors

class BaseA(object):
    authors = ['a', 'b']
    author_list = authors

class BaseB(object):
    authors = ['a', 'b']

    def __init__(self, *arg, **kwargs):
        self.author_list = BaseB.authors + self.authors

class ChildA(BaseA):
    authors = ['c', 'd']

class ChildB(BaseB):
    authors = ['c', 'd']

child_a = ChildA()
child_b = ChildB()
print(child_a.author_list)
print(child_b.author_list)
>>> ['a', 'b']
>>> ['a', 'b', 'c', 'd']

オーバーライド

class BaseA(object):
    authors = ['a', 'b']
    author_list = authors

class BaseB(object):
    authors = ['a', 'b']

    def __init__(self, *arg, **kwargs):
        self.author_list = self.authors

class ChildA(BaseA):
    authors = ['c', 'd']
    def __init__(self, *arg, **kwargs):
        self.author_list = self.authors

class ChildB(BaseB):
    authors = ['c', 'd']

child_a = ChildA()
child_b = ChildB()
print(child_a.author_list)
print(child_b.author_list)
>>> ['c', 'd']
>>> ['c', 'd']
于 2021-01-08T22:43:22.640 に答える
0

Pythonコードを書くための推奨される方法:

class BaseA(object):
    def __init__(self):
        self.authors = ['a', 'b']

class BaseB(object):
    def __init__(self):
        self.authors = ['a', 'b']

class ChildA(BaseA):
    def __init__(self):
        self.authors = ['c', 'd']
    
class ChildB(BaseB):
    def __init__(self):
        self.authors = ['c', 'd']


child_a = ChildA()
child_b = ChildB()
print(child_a.authors)
print(child_b.authors)
>>> ['c', 'd']
>>> ['c', 'd']

スーパークラス(基本親クラス)を呼び出すための推奨される方法:

class BaseA(object):
    def __init__(self):
        self.authors = ['a', 'b']

class BaseB(object):
    def __init__(self):
        self.authors = ['a', 'b']

class ChildA(BaseA):
    def __init__(self):
        self.authors = ['c', 'd']
        super().__init__()
    
class ChildB(BaseB):
    def __init__(self):
        self.authors = ['c', 'd']
        BaseB.__init__(self)


child_a = ChildA()
child_b = ChildB()
print(child_a.authors)
print(child_b.authors)
>>> ['a', 'b']
>>> ['a', 'b']

末尾に1つのアンダースコアを使用した難解なスーパークラス呼び出し__init__ (__init_)

class BaseA(object):
    def __init__(self):
        self.authors = ['a', 'b']

class BaseB(object):
    def __init__(self):
        self.authors = ['a', 'b']

class ChildA(BaseA):
    def __init_(self):
        self.authors = ['c', 'd']
    
class ChildB(BaseB):
    def __init_(self):
        self.authors = ['c', 'd']


child_a = ChildA()
child_b = ChildB()
print(child_a.authors)
print(child_b.authors)
>>> ['a', 'b']
>>> ['a', 'b']

注意

難解なスーパークラス呼び出しを使用すると、子変数へのすべてのアクセスが失われます。

サブクラス(子クラス)のメソッドへのアクセスは引き続きアクセス可能ですが、サブクラス(子クラス)の変数へのすべてのアクセスは完全に失われます。

于 2021-01-08T23:54:09.933 に答える