Python - why use "self" in a class?
A.x
is a class variable.
B
's self.x
is an instance variable.
i.e. A
's x
is shared between instances.
It would be easier to demonstrate the difference with something that can be modified like a list:
#!/usr/bin/env python
class A:
x = []
def add(self):
self.x.append(1)
class B:
def __init__(self):
self.x = []
def add(self):
self.x.append(1)
x = A()
y = A()
x.add()
y.add()
print("A's x:", x.x)
x = B()
y = B()
x.add()
y.add()
print("B's x:", x.x)
Output
A's x: [1, 1]
B's x: [1]
Just as a side note: self
is actually just a randomly chosen word, that everyone uses, but you could also use this
, foo
, or myself
or anything else you want, it's just the first parameter of every non static method for a class. This means that the word self
is not a language construct but just a name:
>>> class A:
... def __init__(s):
... s.bla = 2
...
>>>
>>> a = A()
>>> a.bla
2
A.x is a class variable, and will be shared across all instances of A, unless specifically overridden within an instance. B.x is an instance variable, and each instance of B has its own version of it.
I hope the following Python example can clarify:
>>> class Foo():
... i = 3
... def bar(self):
... print 'Foo.i is', Foo.i
... print 'self.i is', self.i
...
>>> f = Foo() # Create an instance of the Foo class
>>> f.bar()
Foo.i is 3
self.i is 3
>>> Foo.i = 5 # Change the global value of Foo.i over all instances
>>> f.bar()
Foo.i is 5
self.i is 5
>>> f.i = 3 # Override this instance's definition of i
>>> f.bar()
Foo.i is 5
self.i is 3
I used to explain it with this example
# By TMOTTM
class Machine:
# Class Variable counts how many machines have been created.
# The value is the same for all objects of this class.
counter = 0
def __init__(self):
# Notice: no 'self'.
Machine.counter += 1
# Instance variable.
# Different for every object of the class.
self.id = Machine.counter
if __name__ == '__main__':
machine1 = Machine()
machine2 = Machine()
machine3 = Machine()
#The value is different for all objects.
print 'machine1.id', machine1.id
print 'machine2.id', machine2.id
print 'machine3.id', machine3.id
#The value is the same for all objects.
print 'machine1.counter', machine1.counter
print 'machine2.counter', machine2.counter
print 'machine3.counter', machine3.counter
The output then will by
machine1.id 1 machine2.id 2 machine3.id 3 machine1.counter 3 machine2.counter 3 machine3.counter 3