I have this code with a class:
class Triangle(object):
def __init__(self, side1, side2, side3):
self.side1 = side1
self.side2 = side2
self.side3 = side3
def perimeter(self):
return "Perimeter = %s" % (side1 + side2 + side3)
a = Triangle(3, 4, 5)
print(a.perimeter())
Running this code throws an exception:
Traceback (most recent call last):
File "untitled.py", line 12, in <module>
print(a.perimeter())
File "untitled.py", line 9, in perimeter
return "Perimeter = %s" % (side1 + side2 + side3)
NameError: name 'side1' is not defined
How come I can't access side1
in the perimeter
method?
Replace
return "Perimeter = %s" %(side1 + side2 + side3)
To
return "Perimeter = %s" %(self.side1 + self.side2 + self.side3)
You missed to add self
This line:
return "Perimeter = %s" %(side1 + side2 + side3)
should be:
return "Perimeter = %s" %(self.side1 + self.side2 + self.side3)
To return the value of member variables in python, self.
must be before the member. This is why self is one of the required parameters for member methods. In many other languages such as C#, the passing of self
is implied, so you don't have to manually write it into the code.
Unlike many other languages, python does not allow implicit access to instance attributes. To access an attribute in python, you must explicitly prefix it with self.
like this:
return "Perimeter = %s" % (self.side1 + self.side2 + self.side3)
Without the self.
prefix, python considers side1
to be a local or global variable.
The same thing applies to methods. For example, if you wanted to call perimeter
from __init__
, this would not work:
def __init__(self, side1, side2, side3):
self.side1 = side1
self.side2 = side2
self.side3 = side3
perimeter()
Instead, you would have to write
self.perimeter()
See also this related question.