Variable scopes in Python classes
Solution 1:
Since the listing in your question is not 100% clear, I've decided to explain it with a simple example. It also includes some things like __something
variables you did not mention in your list.
class Test:
a = None
b = None
def __init__(self, a):
print self.a
self.a = a
self._x = 123
self.__y = 123
b = 'meow'
At the beginning, a
and b
are only variables defined for the class itself - accessible via Test.a
and Test.b
and not specific to any instance.
When creating an instance of that class (which results in __init__
being executed):
-
print self.a
doesn't find an instance variable and thus returns the class variable -
self.a = a
: a new instance variablea
is created. This shadows the class variable soself.a
will now reference the instance variable; to access the class variable you now have to useTest.a
- The assignment to
self._x
creates a new instance variable. It's considered "not part of the public API" (aka protected) but technically it has no different behaviour. - The assignment to
self.__y
creates a new instance variable named_Test__y
, i.e. its name is mangled so unless you use the mangled name it cannot be accessed from outside the class. This could be used for "private" variables. - The assignment to
b
creates a local variable. It is not available from anywhere but the__init__
function as it's not saved in the instance, class or global scope.
Solution 2:
Declaring a variable at the top level of the class is like declaring a static or class variable. Qualifying it with self is declaring an instance variable. Class variables can be modified by referring to them by class name (e.g. Class.x = 5
) and all instances will inherit these changes. Instance variables are private to an instance and can only be modified by that instance.
You can achieve some level of access control using underscores. See private variables in the Python tutorial. By convention, variables starting with one underscore, e.g. _foo
are non-public parts of an API, and names starting with two underscores e.g. __foo
will have it's name mangled to be _classname__foo
.