I am trying to create a json string from a class and I defined my class as follows:
import json
import ast
from datetime import datetime
import pytz
import time
class OuterClass:
def __init__(self):
self.Header = None
self.Body = None
class Header:
def __init__(self, ID = None, Name = None):
self.ID = ID
self.Name = Name
class Body:
def __init__(self, DateTime=None, Display=None):
self.DateTime = DateTime
self.Display = Display
def current_time_by_timezone(timezone_input):
return datetime.now(pytz.timezone(timezone_input))
if __name__ == '__main__':
response = OuterClass()
header = response.Header('123', 'Some Name')
body = response.Body(current_time_by_timezone('US/Central'), 'NOT VALID')
print(json.dumps(response.__dict__))
I’m getting an error ‘TypeError: ‘NoneType’ object is not callable’. Is it because I’m setting the Header and Body in the OuterClass definition myself to None?
Advertisement
Answer
The problem with your code is these lines:
self.Header = None
self.Body = None
These create instance variables named Header
and Body
on every instance of OuterClass
, so you can never access the class variables (the nested classes) via an instance, only via OuterClass
itself.
It’s not very clear what your intention is with this data structure. Defining a class inside another class doesn’t do anything special in Python (by default, you could probably make there be special behavior with special effort, like using a metaclass that makes the inner classes into descriptors). Generally though, there’s no implied relationship between the classes.
If you want your OuterClass
to create instances of the other two classes, you can do that without nesting their definitions. Just put the class definitions at top level and write a method that creates an instance at an appropriate time and does something useful with it (like binding it to an instance variable).
You might want something like:
def Header:
def Response:
def __init__(self):
self.header = None
def make_header(self, *args):
self.header = Header(*args)
return self.header
You could keep the classes nested as long as you don’t expect that to mean anything special, just be sure that you don’t use the class name as an instance variable, or you’ll shadow the name of the nested class (a capitalization difference, like self.header
vs self.Header
could be enough).