Reputation: 2391
While initializing a class, the default arg for a parameter is a constant class attribute.
class SomeClass:
"""Some class."""
DEFAULT_VAL = 0
def __init__(self, some_param: int = DEFAULT_VAL):
print(f"default = {self.DEFAULT_VAL} and some_param = {some_param}.")
some_class = SomeClass()
Prints: default = 0 and some_param = 0.
When I subclass the class, and override the constant class attribute, it doesn't use it as the default parameter.
class SomeChildClass(SomeClass):
"""Some child class."""
DEFAULT_VAL = 1
some_child_class = SomeChildClass()
Prints: default = 1 and some_param = 0.
Is there some way I can make this work, without explicitly overriding __init__
in the child class?
Research
How to call parent class init with default values from child class?
Question is very similar, yet they override __init__
.
Reinitialize parent class attributes during child class definition
Presents a possible solution using a metaclass
to specify DEFAULT_VAL
via __new__
. This solution adds verbosity to SomeClass
, which is not half bad. I am wondering if it can be done even simpler though.
Overriding class variables in python
In this answer, it informs me the problem is that DEFAULT_VAL
is evaluated when the function __init__
is defined. However, I am not quite sure if using a classmethod
is applicable in my use case.
Upvotes: 0
Views: 725
Reputation: 95873
The problem here is that default values take objects, not variables/attributes. The object is evaluated once when the function is defined. The generic way to solve this in any function is to do something like:
class SomeClass:
"""Some class."""
DEFAULT_VAL = 0
def __init__(self, some_param: int = None):
if some_param is None:
some_param = self.DEFAULT_VAL
print(f"default = {self.DEFAULT_VAL} and some_param = {some_param}.")
Upvotes: 2