4

What's the difference between self.x+self.y and x+y in the code below?

class m2:
    x, y = 4, 5
    def add(self, x, y):
        return self.x + self.y
    def add2(self, x, y):
        return x + y

>>> x = m2()
>>> print "x.add(self.x + self.y = )", x.add(1, 2)
x.add(self.x + self.y = ) 9
>>> print "x.add2(x + y = )", x.add2(1, 2)
x.add2(x + y = ) 3

Why does self.x + self.y return 9 vs x + y returns 3?

Mauro Baraldi
  • 6,346
  • 2
  • 32
  • 43
skp_888
  • 77
  • 1
  • 2
  • Possible duplicate of [Python: Difference between class and instance attributes](http://stackoverflow.com/questions/207000/python-difference-between-class-and-instance-attributes) – idjaw Feb 26 '16 at 16:56
  • 2
    @idjaw I don't think this is a duplicate of the question you linked. There isn't a single instance attribute in this question, so it's not about confusing class and instance attributes. – Sven Marnach Feb 26 '16 at 16:59
  • 6
    In the first, `add`, you are adding the values of the properties of the `self` object. In the second, `add2`, you are adding the values of the arguments. – Dan D. Feb 26 '16 at 17:00
  • @SvenMarnach I jumped the gun. Thanks for bringing it up. Retracting. – idjaw Feb 26 '16 at 17:00

5 Answers5

3

In add you are calling the class variables and ignoring the method arguments x and y.

class m2:

    # these variables are class variables and are accessed via self.x and self.y
    x, y = 4, 5  

    def add(self, x, y):
        return self.x + self.y  # refers to 4 and 5

    def add2(self, x, y):
        return x + y  # refers to input arguments x and y, in your case 1 and 2

When defining x and y in the class scope it makes them class variables. They are part of the the class m2 and you don't even need to create an instance of m2 to access them.

print m2.x, m2.y
>> 4, 5

However, you are also able to access them via an instance as if they were instance variables like this:

m = m2()
print m.x, m.y
>> 4, 5

The reason behind this is that the interpreter will look for instance variables with names self.x and self.y, and if they are not found it will default to class variables.

Read more about class attributes in the python documentation.

Forge
  • 6,538
  • 6
  • 44
  • 64
1

The difference is that when you use self you refer to the member of the instance of your class

When you use X and Y dirrectly you refer to the parameter that you use in your function

This is a simplification of your class

class m2:
    x_member1, y_member2 = 4, 5
    def add(self, x_parameter1, y_parameter2 ):
            return self.x_member1+ self.y_member2
    def add2(self, x_parameter1, y_parameter2 ):
            return x_parameter1 + y_parameter2
Mr Rubix
  • 1,492
  • 14
  • 27
1

When a class method is called, the first argument (named self by convention) is set to the class instance. When the method accesses attributes of self, it is accessing those attributes in the class instance, and their values persist in that instance.

On the other hand, if a class method accesses bare variables, those variables are strictly local to those methods and their values do not persist across calls to class methods of that instance.

Tom Karzes
  • 22,815
  • 2
  • 22
  • 41
1
class m2:
    x, y = 4, 5 #This are class attributes
    def add(self, x, y ):
            return self.x + self.y # This are instance variables
    def add2(self, x, y ):
            return x + y # This are local variables

Class variables are common to each instance of the class. Instance variables are only avaible to that instance. And local variables are only avaible in the scope of the function.

In add, when you do self.x it's refering to the class variable x cause it's also part of the instance. In add2 it's refering to local variables

The same results could be achieved if those methods were class methods or static methods (With proper adjustments)

Class method:

class m2:

    x, y = 4, 5

    @classmethod
    def add(cls, x, y):
        return cls.c + cls.y #Here you're calling class attributes

    @classmethod
    def add2(cls, x, y):
        return x + y

Results:

>>> m.add(1,2)
9
>>> m.add2(1,2)
3

Static method:

class m2:
    x, y = 4, 5

    @staticmethod
    def add(x, y):
        return m2.c + m2.y #Here you need to call the class attributes through the class name

    @staticmethod
    def add2(x, y):
        return x + y

Results:

 >>> m2.add(1,2)
 9
 >>> m2.add2(1,2)
 3
Community
  • 1
  • 1
Mr. E
  • 2,070
  • 11
  • 23
0

x and y will be local by default. The self.x and self.y are persisted in that instance, x and y will only be there locally.

class Dog():
    def __init__(self):
        x = "local"
        self.y = "instance"

d = Dog()
print(d.y)
#=> instance
print(d.x)
#=> AttributeError: Dog instance has no attribute 'y'
Nathan Hinchey
  • 1,191
  • 9
  • 30