Let's say I have the following class
class Parent(object):
Options = {
'option1': 'value1',
'option2': 'value2'
}
And a subclass called Child
class Child(Parent):
Options = Parent.Options.copy()
Options.update({
'option2': 'value2',
'option3': 'value3'
})
I want to be able to override or add options in the child class. The solution I'm using works. But I'm sure there is a better way of doing it.
EDIT
I don't want to add options as class attributes because I have other class attributes that aren't options and I prefer to keep all options in one place. This is just a simple example, the actual code is more complicated than that.
Semantically equivalent to your code but arguably neater:
class Child(Parent):
Options = dict(Parent.Options,
option2='value2',
option3='value3')
Remember, "life is better without braces", and by calling dict
explicitly you can often avoid braces (and extra quotes around keys that are constant identifier-like strings).
See http://docs.python.org/library/stdtypes.html#dict for more details -- the key bit is "If a key is specified both in the positional argument and as a keyword argument, the value associated with the keyword is retained", i.e. keyword args override key-value associations in the positional arg, just like the update
method lets you override them).
One way would be to use keyword arguments to dict to specify additional keys:
Parent.options = dict(
option1='value1',
option2='value2',
)
Child.options = dict(Parent.options,
option2='value2a',
option3='value3',
)
If you want to get fancier, then using the descriptor protocol you can create a proxy object that will encapsulate the lookup. (just walk the owner.__mro__ from the owner attribute to the __get__(self, instance, owner) method). Or even fancier, crossing into the probably-not-a-good-idea territory, metaclasses/class decorators.
After thinking more about it, and thanks to @SpliFF suggestion this is what I came up with:
class Parent(object):
class Options:
option1 = 'value1'
option2 = 'value2'
class Child(Parent):
class Options(Parent.Options):
option2 = 'value2'
option3 = 'value3'
I'm still open to better solutions though.
Why not just use class attributes?
class Parent(object):
option1 = 'value1'
option2 = 'value2'
class Child(Parent):
option2 = 'value2'
option3 = 'value3'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With