0

In the example below, classes AA and BB are instantiated with params a and b and feature the foo method. The only difference between classes AA and BB is that in the AA foo method, the intermediate variable z is prefixed with the class instance reference self while in class BB it is not. What is the correct methodology here? When should self be used within class methods and when should it not be used? I've always been confused by this!

class AA:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def foo(self):
        self.z = self.a + self.b
        return self.z * self.a

class BB:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def foo(self):
        z = self.a + self.b
        return z * self.a
wjandrea
  • 28,235
  • 9
  • 60
  • 81
user2238328
  • 259
  • 2
  • 6
  • 16
  • 4
    If you don't need to preserve the value of `z` as an instance attribute, the second form (where `z` is just a local variable) is fine. – sj95126 Oct 24 '22 at 00:15
  • That title is pretty vague. It might be better to switch it to something like "When should I assign an intermediate variable to the class instance in a method?" See [ask] for tips on writing a good title. – wjandrea Oct 24 '22 at 00:41
  • `self` refers to the instance. So you use it when you want to refer to the instance. It has **no special meaning** and is **just** a name for a parameter. All the magic happens when the method is called. – Karl Knechtel Oct 24 '22 at 00:52
  • Note that lazily initialized attributes (assigned at unpredictable points after `__init__` is done) break [PEP 412: Key-sharing dictionaries](https://peps.python.org/pep-0412/); if you make a lot of these instances, the extra memory overhead of initializing late will hurt. – ShadowRanger Oct 24 '22 at 22:32

2 Answers2

2

Neither one is "correct" per se. It depends what you want to do: If you want to keep the value around, then you could assign it to the instance. If not, then don't.

Although, if you do assign it as a public instance attribute, you'll probably want to set an initial value in __init__(), like None.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
  • 1
    Got it thanks, so really it is a question of whether the variable needs to be kept in memory for use elsewhere. Appreciate it! – user2238328 Oct 24 '22 at 00:59
-2

the use of the self will appear when you initiate an object from the class, so in order that the object will have an access to the variable you need to use the self

class AA:
def __init__(self, a, b):
    self.a = a
    self.b = b

def foo(self):
    self.z = self.a + self.b
    return self.z * self.a

class BB:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def foo(self):
        z = self.a + self.b
        return z * self.a
A = AA(1, 2)
A.foo()
print(A.z) # will print the value
B = BB(1, 2)
B.foo()
print(B.z) # will not print the value, "z" attribute is not defined
HichamDz38
  • 94
  • 7