二重アンダースコアは 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