So I am trying to create a class with an initialization method that needs to get the type of the object being created in order to properly set the default values of the init arguments.
To give a concrete example with code, say I have the following class:
def __init__(self, foo, bar=type(self).some_class_variable, ham=type(self).some_other_class_variable):
self.foo = foo
self.bar = bar
self.ham = self.some_function(ham)
This is the functionality I am looking for, but my IDE is saying "self" is not defined
which I can understand, as self
has yet to be instantiated. So my question is how would I go about implementing this properly? I do not want to "hardcode" the class type in where I currently have type(self)
because subclasses of this class may have their own values for some_class_variable
and some_other_class_variable
and I want those subclasses to use the class variable corresponding to their type.
My solution needs to work in Python 3.6 & Python 3.7 but I would really prefer to find a solution that works in all versions of Python 3.6 and later if possible.
CodePudding user response:
I think that you should put it in the body, not the parameter.
def __init__(self, foo):
self.foo = foo
self.bar = type(self).some_class_variable
self.ham = self.some_function(type(self).some_other_class_variable)
EDIT: If the values are defaults, you can do this:
default_value = 'default pls'
def __init__(self, foo, bar=default_value, ham=default_value):
self.foo = foo
if default_value == bar:
self.bar = type(self).some_class_variable
if default_value == ham:
self.ham = self.some_function(type(self).some_other_class_variable)
CodePudding user response:
The class name is not bound yet, as the class has not been initialised at that point. See this answer which explains this in more depth.
A way to work-around this, albeit not that great, is to create setter methods for the variables, and to set them after an instance has been initialised, like so:
class Example:
def __init__(self, foo):
self.foo = foo
self.bar = None
self.ham = None
def set_bar(self, bar):
self.bar = bar
def set_ham(self, ham):
self.ham = ham
You can go one step further to validate the type of those attributes with a simple if statement, or through python 'typing'.