I'm creating a structure of classes for a wrapper of an API I'm currently writing. I have multiple classes defined inside my models file. I want to assign the default value of some attributes of classes to other classes. When I do this, I get a NameError because sometimes I try to use classes that are defined below the current class, thus Python does not know these classes yet. I've tried multiple solutions but none of them seem to work. Does anybody know an alternative or has experience with this?
my classes I've defined:
class RateResponse(BaseModel):
def __init__(self,
provider=Provider()
):
self.provider = provider
class Provider(ObjectListModel):
def __init__(self):
super(Provider, self).__init__(list=[], listObject=ProviderItem)
@property
def providerItems(self):
return self.list
class ProviderItem(BaseModel):
def __init__(self,
code=None,
notification=Notification(),
service=Service()
):
self.code = code
self.notification = notification
self.service = service
As you can see above, I'm initialising the attribute 'provider' on the class RateResponse with the an empty object of the class Provider, which is defined below it. I'm getting a NameError on this line because it's defined below RateResponse.
provider=Provider()
NameError: name 'Provider' is not defined
The simple solution to above would be to shift the places of the classes. However, this is only a snippet of my file that is currently 400 lines long, all with these types of classes and initializations. It would be impossible to order them all correctly.
I've looked up some solutions where I thought I could return an empty object of a class by a string. I thought the function would only evaluate after all the classes were defined, but I was wrong. This is what I tried:
def getInstanceByString(classStr):
return globals()[classStr]()
class RateResponse(BaseModel):
def __init__(self,
provider=getInstanceByString('Provider')
):
self.provider = provider
But to no avail. Does anybody have experience with this? Is this even possible within Python? Is my structure just wrong? Any help is appreciated. Thanks.
This code might not mean what you want it to mean:
class RateResponse(BaseModel):
def __init__(self,
provider=Provider()
):
...
This code is saying that when this class is declared you want to make an instance of Provider
which will be the default value for the provider
parameter.
You may have meant that the default argument should be a new instance of Provider
for each client that makes an instance of RateResponse
.
You can use the Mutable Default Argument pattern to get the latter:
class RateResponse(BaseModel):
def __init__(self, provider=None):
if provider is None:
provider = Provider()
...
However, if you really do want a single instance when the client wants the default you could add a single instance below the Provider
definition:
class Provider(ObjectListModel):
...
Singleton_Provider = Provider()
Then the RateResponse
class could still use the current pattern, but instead perform this assignment inside the if
:
if provider is None:
provider = Singleton_Provider
At the time that the assignment is performed, the Singleton_Provider
will have been created.