Python - AttributeError

时间:2016-03-08 20:49:56

标签: python

因此,对于我正在进行的线类,我不断收到错误消息

AttributeError: Line instance has no attribute 'point0'

我正在声明这样的界限:

def __init__(self, point0, point1):
    self.x = point0
    self.y = point1

def __str__(self):
    return '%d %d' % (int(round(self.point0)), int(round(self.point1)))

我得到了我的点类中的x和y,它应该已经是浮点值所以我不需要在我的init方法中检查错误但是我确实检查了我的旋转中是否有point0和point1是浮点数方法:

def rotate(self, a):
        if not isinstance(a, float) or not isinstance(self.point0, float) or not isinstance(self.point1, float):
            raise Error("Parameter \"a\" illegal.")
        self.point0 = math.cos(a) * self.point0 - math.sin(a) * self.point1
        self.point1 = math.sin(a) * self.point0 + math.cos(a) * self.point1

那么为什么python一直说它没有属性point0?我还尝试将 init 方法更改为:

def __init__(self, point0, point1):
    self.point0 = point0
    self.point1 = point1

但是当我这样做时,错误说point0没有属性float。那么为什么我一直收到这个错误?这是我用来测试的代码:

p0 = Point(0.0, 1.0)
p1 = Point(2.0, 3.0)
line = Line(p0,p1)
print line

4 个答案:

答案 0 :(得分:1)

我好奇......你对Python的范围了解多少?

在你的班级中,你有一个名为x的成员变量和另一个名为y的变量。您的 init 函数接受一个名为point0的参数,另一个名为point1。它将point0保存在x成员变量中,而point1保存在y中。然后,在您的旋转函数中,您尝试访问名为point0的变量。你看到了问题吗?

编程时要理解的重要事项(在大多数编程语言中都是如此,如果不是全部的话),参数的名称不会影响其他地方的数据名称。我可以将一个名为foo的变量传递给一个带有名为bar的参数的函数。在该函数中,我必须将数据称为bar,因为它是变量的名称。之后,在我调用该函数之后,变量的名称仍然是foo,因为只有函数内部的变量才被称为bar。那有意义吗?

答案 1 :(得分:1)

当你调用它时,你的类接受point0和point1参数。如果您想获取这些参数的值,请使用self.x(for point0)self.y(for point1) 或另一种方式;

class Line:
   def __init__(self, point0, point1):
       self.point0 = point0
       self.point1 = point1

我建议你阅读;

Python __init__ and self what do they do?

https://www.ibiblio.org/swaroopch/byteofpython/read/class-init.html

https://docs.python.org/2/tutorial/classes.html

答案 2 :(得分:0)

我将在这里添加另一个答案,因为我缺乏评论其他答案的声誉,因为我觉得这个答案与我以前的答案无关(它解决了与你现在看到的不同的问题) )。

因此。也就是说,看看这行代码:

return '%d %d' % (int(round(self.point0)), int(round(self.point1)))

round是一个带数字参数的函数。但是,self.point0和self.point1不是数字。他们是积分。如果你想要它们的数字,你必须明确地引用它们(即self.point0.x)。

答案 3 :(得分:0)

在显示更正的代码之前的几个要点。 (注意实际上没有太多变化):

  1. 不要费心检查参数类型。假设Python程序员负责阅读文档并传递正确值的值。

  2. 您的Line课程正在复制您已在Point课程中定义的代码。行的属性是Point个实例,因此您可以使用您定义的方法来实现Line方法。

  3. 显示它们时没有理由将点坐标舍入为整数;显示定义点的实际浮点值。您的Line.__str__方法可以利用您已定义Point.__str__的事实。

  4. 现在,你的代码更短,更正,并附有一些散布的评论。

    import math
    
    
    class Point:
        def __init__(self, x, y):
            '''x and y should be floats'''
            self.x = x
            self.y = y
    
        def rotate(self, a):
            '''Rotate the point around the origin by a radians'''
            self.x = math.cos(a) * self.x - math.sin(a) * self.y
            self.y = math.sin(a) * self.x + math.cos(a) * self.y
            # If you *were* going to check if a is a float, you
            # need to do it *before* you use it.
    
        def scale(self, f):
            '''Scale the point by f units'''  # you get the idea
            self.x = f * self.x
            self.y = f * self.y
    
        def translate(self, delta_x, delta_y):
            self.x = self.x + delta_x
            self.y = self.y + delta_y
    
        def __str__(self):
            # If you're storing floats, it's probably useful
            # to output them.
            return '(%f, %f)' % (self.x, self.y)
    
    
    # Operations on a line all involve applying the same operations
    # to each of its end points.
    class Line:
        def __init__(self, point0, point1):
            self.point0 = point0
            self.point1 = point1
    
        def rotate(self, a):
            self.point0.rotate(a)
            self.point1.rotate(a)
    
        def scale(self, factor):
            self.point0.scale(factor)
            self.point1.scale(factor)
            # If for whatever reason you didn't want to use Point.scale
            # here, the code would be...
            # self.point0.x = f * self.point0.x
            # self.point0.y = f * self.point0.y
            # self.point1.x = f * self.point0.x
            # self.point1.y = f * self.point0.y
    
        def translate(self, delta_x, delta_y):
            self.point0.translate(delta_x, delta_y)
            self.point1.translate(delta_x, delta_y)
    
        def __str__(self):
            # You've already defined out to turn a Point into
            # a string, so you can take advantage of that here.
            return "%s -- %s" % (self.point0, self.point1)