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).