Python – why use "self" in a class?

Question:

How do these 2 classes differ?

class A():
    x=3

class B():
    def __init__(self):
        self.x=3

Is there any significant difference?

Asked By: ryeguy

||

Answers:

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]
Answered By: Douglas Leeder

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
Answered By: TerrorBite

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
Answered By: André

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
Answered By: TMOTTM

I’ve just started learning Python and this confused me as well for some time. Trying to figure out how it all works in general I came up with this very simple piece of code:

# Create a class with a variable inside and an instance of that class
class One:
    color = 'green'

obj2 = One()


# Here we create a global variable(outside a class suite).
color = 'blue'         

# Create a second class and a local variable inside this class.       
class Two:             
    color = "red"

    # Define 3 methods. The only difference between them is the "color" part.
    def out(self):     
        print(self.color + '!')

    def out2(self):
        print(color + '!')

    def out3(self):
        print(obj2.color + '!')

# Create an object of the class One
obj = Two()

When we call out() we get:

>>> obj.out()

red!

When we call out2():

>>> obj.out2()

blue!

When we call out3():

>>> obj.out3()

green!

So, in the first method self specifies that Python should use the variable(attribute), that “belongs” to the class object we created, not a global one(outside the class). So it uses color = "red". In the method Python implicitly substitutes self for the name of an object we created(obj). self.color means “I am getting color="red" from the obj

In the second method there is no self to specify the object where the color should be taken from, so it gets the global one color = 'blue'.

In the third method instead of self we used obj2 – a name of another object to get color from. It gets color = 'green'.

Answered By: yabee-dabee
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.