二重アンダースコアは Python で特別な意味を持つため、インスタンス変数の先頭で二重アンダースコアを使用しないでください。
インスタンス変数の識別子が 2 つのアンダースコアで始まる場合、サブクラスの名前空間での衝突を避けるために「名前がマングル」され、self.__collections
実際には になりself._Base__collections
ます。インスタンス変数識別子の先頭と末尾にある二重アンダースコアは、特別なメソッドと特別な名前 (__add__
または など__class__
) のために予約されています。
インスタンス変数は、collections
プライベートであることを示すために、文字 (例: ) または単一のアンダースコア(例: _collections
)で始まる必要があります。
とにかく、あなたの例でcollection
は、存在しない属性を設定しています。クラスで属性self.collection
に名前を付けると、Base
正しく機能します。
明確にするために:
>>> class Base(object):
... def __init__(self, collection=None):
... self.__collection__ = collection or self.__class__.__name__
...
>>> class Thing(Base):
... def __init__(self, **kwargs):
... super(Thing, self).__init__()
... self.__dict__.update(kwargs)
...
>>> t = Thing(collection=3) __dict__.update creates a new instance attribute
>>> t.__collection__
'Thing'
>>> t.collection # here it is
3
>>> t = Thing(**{'__collection__': 7}) #UGLY! Do not do this!!!
>>> t.__collection__
7