Reputation: 19807
I want to inherit the collection
arg from the Base
class. How?
class Base(object):
def __init__(self, collection=None, classname=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='foobar')
t.__collection__
>>> 'Thing'
:(
Upvotes: 0
Views: 177
Reputation: 101979
Do not use double underscores at the beginning of an instance variable, and avoid using them at the beginning and at the end, because double underscore has a special meaning in python.
If an instance variable's identifier starts with a double underscore it is "name mangled" to avoid clashes in the namespaces of the subclasses, and thus self.__collections
actually becomes self._Base__collections
.
Double underscore at the beginning and end of an instance variable identifier are reserved for special methods and special names(e.g. __add__
or __class__
).
Instance variables should either start with a letter(e.g. collections
) or a single underscore to denote that they are private(e.g. _collections
)
Anyway, in your example you are setting a collection
attribute which does not exist. If you named the attribute self.collection
in the Base
class it would work correctly.
To make clear:
>>> 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
Upvotes: 0
Reputation: 7790
I don't usually use super()
. I instead call the __init__
function directly. Something like:
class Base(object):
def __init__(self, collection=None, classname=None):
self.__collection__ = collection or self.__class__.__name__
class Thing(Base):
def __init__(self, **kwargs):
#super(Thing, self).__init__()
Base.__init__(self, **kwargs)
#self.__dict__.update(kwargs)
t = Thing(collection='foobar')
print(t.__collection__)
Should yield what you want.
Upvotes: 1
Reputation: 251408
Are you looking for super(Thing, self).__init__(**kwargs)
? This will pass the keyword arguments along to the superclass __init__
.
Upvotes: 0
Reputation: 730
You just need to 'forward' the kwargs
to your base class' __init__()
method:
class Thing(Base):
def __init__(self, **kwargs):
super(Thing, self).__init__(**kwargs)
self.__dict__.update(kwargs)
t = Thing(collection='foobar')
assert t.__collection__ == 'foobar'
assert t.__dict__.get('collection') == 'foobar'
You were simply calling Base.__init__()
with default arguments.
Upvotes: 0