1

I'm creating a server like this:

server = HTTPServer(('', PORT_NUMBER), MyHandler)

...and then the handler:

class MyHandler(BaseHTTPRequestHandler):
    x = 0
    some_object = SomeClass()

    def do_GET(self):
        print self.x
        self.x += 1
        # etc. but x is not used further

class SomeClass:
    def __init__(self):
        print "Initialising SomeClass"

Now, everytime I make a get request, the value printed for self.x is always 0. However, the SomeClass constructor is only called once, when the server is first fired up (I'm assuming this is the case because the print message in the constructor is only called once).

The fact that self.x keeps resetting for every request suggests that the handler class is recreated new for each request, but the fact that the SomeClass message only prints once contradicts this.

Can someone tell me what's going on here?

RTF
  • 6,214
  • 12
  • 64
  • 132

1 Answers1

2

It doesn't contradict anything. Because you're calling SomeClass() in the class definition (rather than __init__), it's called when the class is defined, not when it is instantiated.

What happens when self.x += 1 is called, is that the value of self.x is read from the class level, but then the assignment is made on the instance level, so a new x is created that is specific to the instance.

You could try changing it from self.x to MyHandler.x and see what happens.

Amber
  • 507,862
  • 82
  • 626
  • 550
  • Its because 0 is an immutable object. The first `self.x += 1` grabs the class level value, increments it, and creates an object level variable for the result. Future `self.x += 1` expressions get the object level variable. Its the same as `self.x = MyHandler.x + 1`. – tdelaney Aug 21 '13 at 18:36
  • Yes, changing self.x to MyHandler.x did fix it, thanks. But I'm afraid I don't understand why. I'm actually new to Python. Are variables created in the class definition static i.e. shared among all instances, like you said? Would the equivalent of a Java instance variable be declared in __init__ like self.x – RTF Aug 21 '13 at 18:36
  • If I could just ask another question, is the bottom line here, confine variable assignments outside of any functions in a class to constants? As best practice? – RTF Aug 21 '13 at 18:45
  • @RTF no, it's more like... if something should be a class-wide attribute, use it as one. – Amber Aug 21 '13 at 18:57