当我尝试访问类中的属性时,为什么会出现NameError?

时间:2018-06-04 07:21:34

标签: python python-2.7 class attributes nameerror

我有一个类的代码:

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())

运行此代码会引发异常:

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

为什么我无法使用side1方法访问perimeter

3 个答案:

答案 0 :(得分:1)

这一行:

return "Perimeter = %s" %(side1 + side2 + side3)

应该是:

return "Perimeter = %s" %(self.side1 + self.side2 + self.side3)

要在python中返回成员变量的值,self.必须在成员之前。这就是self是成员方法所需参数之一的原因。在许多其他语言(如C#)中,隐含了self的传递,因此您无需手动将其写入代码。

答案 1 :(得分:0)

替换

return "Perimeter = %s" %(side1 + side2 + side3)

return "Perimeter = %s" %(self.side1 + self.side2 + self.side3)

您错过了添加self

答案 2 :(得分:-1)

与许多其他语言不同,python不允许隐式访问实例属性。要在python中访问属性,必须使用self.明确地为其添加前缀,如下所示:

return "Perimeter = %s" % (self.side1 + self.side2 + self.side3)

如果没有self.前缀,python会将side1视为本地或全局变量。

同样的方法适用于方法。例如,如果您想从perimeter拨打__init__,则无效:

def __init__(self, side1, side2, side3):
    self.side1 = side1
    self.side2 = side2
    self.side3 = side3

    perimeter()

相反,你必须写

self.perimeter()

另见this related question