How to define a default list of attributes for instances of a class?
I think Hugh Bothwell is on the right track, but it can be done more concisely:
class MyClass(object):
_defaults = "attr1", "attr2", "attr3"
_default_value = None
def __init__(self, **kwargs):
self.__dict__.update(dict.fromkeys(self._defaults, self._default_value))
self.__dict__.update(kwargs)
my_object = MyClass(attr3='overridden', attr4='added')
print(vars(my_object))
Output:
{'attr4': 'added', 'attr2': None, 'attr3': 'overridden', 'attr1': None}
I made _defaults
and _default_value
class attributes (which could be changed at runtime). (Providing a mutable default value would likely require additional code to prevent it from being shared by every instance created, however.)
This would be easy to extend to allow defining different (immutable) default values for each default attribute:
class MyClass(object):
_defaults = {
"attr1": None,
"attr2": 0,
"attr3": ""
}
def __init__(self, **kwargs):
self.__dict__.update(self._defaults)
self.__dict__.update(kwargs)
my_object = MyClass(attr3='overridden', attr4='added')
print(vars(my_object))
Output:
{'attr4': 'added', 'attr2': 0, 'attr3': 'overridden', 'attr1': None}
Like this?
class MyObject(object):
def __init__(self, attr1 = default1, attr2 = default2):
self.attr1 = attr1
self.attr2 = attr2
You can instantiate a MyObject
with or without specifying the attributes
myObject1 = MyObject() # gets default values
myObject2 = MyObject(foo, bar) # overrides defaults
You could also use keyword arguments (kwargs
) if you have a variable number of attributes, see here for examples.
If you have many properties to be passed, it may be more readable this way:
class Myclass(object):
def __init__(self, **kwargs):
defaults = {
"attr1": None,
"attr2": 0,
"attr3": ""
}
defaults.update(kwargs)
for attr,value in defaults.iteritems():
self.__setattr__(attr, value)
Edit: looking at @martineau and @kosii's suggestions, here is another possibility:
class MyClass(object):
defaults = {
"attr1": None,
"attr2": 0,
"attr3": ""
}
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def __getattr__(self, key):
try:
# return a default value
return MyClass.defaults[key]
except KeyError:
raise AttributeError("don't recognize .{}".format(key))
... in this case, recognized object attributes return default values if they have not actually been set yet.