Mind the gap – Java developers on Python
[UPDATE - didn't understand as much as I thought I did. I think my third assignment is just telling Python that the class and my maprequest3 are the same object. Back to the drawing board)
So here is a little gotcha for Java (and probably .NET) developers when do OO work in Python. When coding in Python it is possible to change the default value of the Class at runtime.
Almost all the examples of OO in python show all the instance variables being set in the constructor but I didn’t want to do that. So I started digging into some open source python projects – like shapely and saw the _ in front of the instance variables and thought that might be the key. It is not. _ in front of a variable is only a coding convention to other developers that this should be treated as private.
In re-reading the docs and playing with code I finally figured it out.
Here is the code that I used to look at what was happening:
First the objects
class GenericRequest: RID = Nonedef getRID(self): return self.RIDdef __init__(self): passclass MapRequest(GenericRequest): _imgDims = None def __init__(self): GenericRequest.__init__(self)
Now the test code
print(MapRequest.__dict__)
MapRequest.RID = "You are screwed"
print(MapRequest.__dict__)
maprequest1 = MapRequest()
maprequest2 = MapRequest()
maprequest1.RID = "hello"
maprequest2.RID = "goodbye"
maprequest1.imgID = "image"
print(maprequest1.RID + " ::: " + maprequest2.RID)
print(maprequest1.getRID() + " ::: " + maprequest2.getRID())
print(maprequest1.__dict__)
MapRequest.RID = "You are screwed"
maprequest3 = MapRequest
print(maprequest3.__dict__)
and the output is
{'_imgDims': None, '__module__': 'requests', '__doc__': None, '__init__': }
{'_imgDims': None, '__module__': 'requests', 'RID': 'You are screwed', '__doc__': None, '__init__': }
hello ::: goodbye
hello ::: goodbye
{'RID': 'hello', 'imgID': 'image'}
{'_imgDims': None, '__module__': 'requests', 'RID': 'You are screwed', '__doc__': None, '__init__': }
changed something
So what we see is that the MapRequest.RID actually changes the value in the class and new instantiated objects get this new value. We also see that each instance of the class has it’s own private RID – this is like Java
Just a little PSA so that Java developers scouring the web can get their heads around this.

Don’t you mean:
maprequest3 = MapRequest() ?
And newly instantiated objects should only have a RID equal to MapRequest.RID if you explicitly set it to that when you init the object, like:
def __init__(self):
self.RID = MapRequest.RID
There’s some explanation and Java-talk here:
http://bkarak.wizhut.com/www/weblog/2007/13112007.html
Marc
No – if I do MapRequest() then I instantiate a new Python object.
With MapRequest I actually affect the underlying class that is used to instantiate objects in the future.
Look at the output to see
Wait wait – I see what you are talking about. I guess I am now back to being somewhat confused.
So Marc – does that page mean that mapReqest1.RID always returns the instance variable?
The single leading underscore is not quite just a convention. See Alex Martelli’s comment on StackOverflow: http://stackoverflow.com/questions/1301346/the-meaning-of-a-single-and-a-double-underscore-before-an-object-name-in-python/1301557#1301557.
Keep variable resolution order in mind. When you resolve “self.RID”, there’s first a check for a instance variable, and failing that a check for a class variable, and then for a base class variable.
Hey Sean:
Thanks that actually help clears it up as well.
Feeling better about it now. Just trying to get my head around writing good OO code in python.
I knew I should have waited for Sean to set things straight! Learn something every day.