In the following code:
class A(object):
VALUE = 1
def __init__(self, value=VALUE):
self.value = value
class B(A):
VALUE = 2
i’d expect that B().value should be equal to 2, however:
B().value = 1
Is there an elegant way to define a class hierarchy where child classes can just declare class variables they want to override and have them be defaults for the instance variables? I still want to allow for these to be changed on a per-instance level, eg.
b = B(value=3)
This is another default arguments question. The point is that when you write
the code inside the function is compiled and made into a function object. It is at this time — not at call time! — that the default arguments are stored. So by the time you have defined
Bit is too late: the default value offoois already set and changingVALUEwon’t have any effect.If this seems a strange thing to do, suppose
foowas a global function:Then any other code, anywhere, could screw up
fooby doingThis is arguably just as confusing.
To force the lookups to be done at runtime not compile time, you need to put them inside the function:
or (not quite the same but prettier)
(This is different because it will treat any ‘falsy’ value as a sentinel — that is,
0,[],{}etc will all be overwritten byVALUE.)EDIT: @mgilson pointed out another way of doing this:
This is neater in that it doesn’t require you to make a sentinel value (like
Noneorobject(), but it does change the argument specification offooquite fundamentally since now it will accept arbitrary keyword arguments. Your call.