I have a Python/Tornado application that responds to HTTP requests with the following 3 classes:
import tornado.web
class MyClass1(tornado.web.RequestHandler):
x = 1
y = 2
def my_method1(self):
print "Hello World"
class MyClass2(MyClass1):
@tornado.web.authenticated
def get(self):
#Do Something 1
pass
@tornado.web.authenticated
def post(self):
#Do Something 2
pass
class MyClass3(MyClass2):
pass
I would like all instances MyClass2
to have an instance variable m
set to the integer 3. But any instances of MyClass3
should over-ride that and have m
set to the integer 4. How can I do it?
I tried adding the following constructors to MyClass2
and MyClass3
respectively, but then when I try to create an instance of MyClass3
, I get the following error: TypeError: __init__() takes exactly 1 argument (3 given)
MyClass2.init():
def __init__(self):
self.m = 3 # This value will be overridden by a subclass
MyClass3.init():
def __init__(self):
self.m = 4
The tornado.web.RequestHandler
already has a __init__
method and Tornado expects it to take two arguments (plus the self
argument of a bound method). Your overridden versions don't take these.
Update your __init__
methods to take arbitrary extra arguments and pass these on via super()
:
class MyClass2(MyClass1):
def __init__(self, *args, **kwargs):
super(MyClass2, self).__init__(*args, **kwargs)
self.m = 3
@tornado.web.authenticated
def get(self):
#Do Something 1
pass
@tornado.web.authenticated
def post(self):
#Do Something 2
pass
class MyClass3(MyClass2):
def __init__(self, *args, **kwargs):
super(MyClass3, self).__init__(*args, **kwargs)
self.m = 4
You could also use the RequestHandler.initialize()
method to set up per-request instance variables; you may have to use super()
again to pass on the call to the parent class, if your parent class initialize()
does more work than just set self.m
.