I have a python application which is as follows:
global_counter = 0
connections = {}
class SocketHandler():
currentid = 0
def open(self):
global global_counter
global connections
currentid = global_counter
global_counter += 1
connections[currentid] = self
print "WebSocket " + str(currentid) + " opened"
def on_close(self):
global connections
print "WebSocket " + str(currentid) + " closed"
del connections[currentid]
I'm getting the error:
NameError: global name 'currentid' is not defined
on the lines of "open" and "on_close" where I print that I am opening/closing the connection. I defined it in the class, why is it not in scope. Also, I have read that using global variables is bad, but I don't see a way around this. Can someone point out what I should do? Thanks.
currentid
should beself.currentid
since it is a class variable.currentid
is instance attribute, so useself.currentid
instead ofcurrentid
:You don't have implicit access to attributes inside methods, in Python.
A bare name like
currentid
in the line:always looks up a name in the local function scope, then in each enclosing function scope, before trying the global module scope (and then looks at built-ins as a last resort).
currentid
is a class attribute, which won't be found in any of those scopes.To look up an attribute in Python you always need to specify an object in which to look. Though the lookup protocol means the object need not necessarily have the attribute itself; attribute lookup will fall back to the class of the object you specified (and the base classes, if inheritance is involved).
So this would work:
However, I don't think the rest of your code is doing what you think it is either. This line in the
open
method:doesn't set the
currentid
attribute of yourSocketHandler
object. Assigning to a bare name always assigns to a local variable, unless you explicitly declare itglobal
(you appear to be aware of this, since you've used theglobal
keyword). So in theopen
method,currentid
is a local function variable; its value is lost at the end of theopen
method.In fact, your
SocketHandler
objects do not have acurrentid
attribute at all (unless there's more code you haven't shown us). Puttingcurrentid = 0
in the class block doesn't give all theSocketHandler
instances acurrentid
attribute. It gives theSocketHandler
class itself an attributecurrentid
; this is just as thedef open(self):
block creates anopen
attribute (storing a function) on the class object, not on each individual instance.Reading
self.currentid
in theon_close
method will fail to find acurrentid
attribute in the objectself
, so Python will look at the class ofself
which isSocketHandler
. That object does have acurrentid
value, so the result of readingself.currentid
will be0
, whether or not you've previously runopen
on thatSocketHandler
.If you meant to store the
currentid
as an instance variable in eachSocketHandler
, then the line inopen
would need to be:This assigns to the
currentid
attribute of the object referred to byself
. You would also then need to change all the other references tocurrentid
in your methods toself.currentid
.