Python:AttributeError:'Point'对象没有属性'x'

时间:2015-03-24 00:00:43

标签: python attributeerror

Traceback (most recent call last):
line 56, in <module>
    distanceToOne = point1.Distance(pointUser)
line 22, in Distance
    distance = math.sqrt((self.__x - toPoint.x)**2 +(self.__y - toPoint.y)**2 +(self.__z - toPoint.z)**2)
AttributeError: 'Point' object has no attribute 'x'

由于某些原因,每当我到达distanceToOne = point1.Distance(pointUser)后,我会在抓住我的三个点来计算距离之后得到上述错误消息。

如果需要,可以使用以下更好的视图:http://pastie.org/private/vige6oaphkwestdemr5uw

提前感谢您的帮助!

import math
class Point(object):
    def __init__(self, x = 0, y = 0, z = 0, description = 'TBD'):
        self.__x = x
        self.__y = y
        self.__z = z
        self.__description = description

    def SetPoint(self, coords):
        self.__x = coords[0]
        self.__y = coords[1]
        self.__z = coords[2]

    def GetPoint(self):
        return [self.__x, self.__y, self.__z]
    PointCoords = property(GetPoint, SetPoint)

    def Distance(self, toPoint):
        toPoint.PointCoords[0]
        toPoint.PointCoords[1]
        toPoint.PointCoords[2]
        return math.sqrt(
            (self.__x - toPoint.x)**2 +
            (self.__y - toPoint.y)**2 +
            (self.__z - toPoint.z)**2)

    def SetDescription(self, description):
        self.__description = description

    def GetDescription(self):
        return self.__description
    PointDescription = property(GetDescription, SetDescription)

if __name__ == "__main__":
    print "Program 9: Demonstrate how to define a class"

    point2 = Point()
    point1 = Point(10, 54, 788, 'Ploto')
    point2.PointCoords = 77, 2, 205
    point2.PointDescription = 'Mars'
    doAnother = "y"
    while(doAnother == "y"):
        pointX = raw_input("Enter a X Number: ")
        pointY = raw_input("Enter a Y Number: ")
        pointZ = raw_input("Enter a Z Number: ")

        # Constructor - Represent the user's location
        pointUser = Point(pointX, pointY, pointZ, 'Sun')

        distanceToOne = point1.Distance(pointUser)
        distanceToTwo = point2.Distance(pointUser)

        # Comparing the two distances between the two to see which one is the closest
        if (distanceToOne > distanceToTwo):
            closest = point2
        else:
            closest = point1
            print ('You are closest to',closest.PointDescription(), 'which is located at ',closest.PointCoords())
        doAnother = raw_input("Do another (y/n)? ").lower()
    print ('Good Bye!')

5 个答案:

答案 0 :(得分:2)

实际错误是由于访问toPoint.x而导致的,因为您从未对其进行定义,因此不存在。

在相关说明中,使用双下划线添加属性会激活pythons name mangling功能。实际属性仍可在课堂外my_point._Point__xmy_point._Point__y等公开访问。

作为一种风格问题,在这种情况下似乎没有任何理由使用名称修改。此功能的预期用例是为了避免与继承的类冲突,它并不是真的想要使私有&#34;私有&#34;变量(为此,约定是使用单个下划线来指示属性何时是实现细节)。

在您的情况下,我认为您应该通常xy等来命名(和访问)属性。在python中,我们通常不会为类成员编写getter和setter除非有特殊要求,因为Python is not Java

答案 1 :(得分:1)

在Distance()的返回行中,__ x而不是x(y和z相同),因为Point类的实例没有x,y z属性,但它们具有__x,__ y,__ z属性。

def Distance(self, toPoint):
    toPoint.PointCoords[0]
    toPoint.PointCoords[1]
    toPoint.PointCoords[2]
    return math.sqrt(
        (self.__x - toPoint.__x)**2 +
        (self.__y - toPoint.__y)**2 +
        (self.__z - toPoint.__z)**2)

答案 2 :(得分:0)

您可以公开访问Point类的xyz属性。如果您希望客户端能够读取但不能写入,则可以使用property。例如:

class Point(object):
    def __init__(self, x = 0, y = 0, z = 0, description = 'TBD'):
        self.__x = x
        self.__y = y
        self.__z = z
        self.__description = description

    @property
    def x(self):
        return self.__x

    @property
    def y(self):
        return self.__y

    @property
    def z(self):
        return self.__z

    ...

然后,您可以在没有前导下划线的情况下访问x,y和z,并且您的距离函数应该可以正常工作。

>>> p = Point(1, 2, 3, 'Dummy')
>>> p.x
1
>>> p.y
2
>>> p.z
3
>>> p.x = 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

答案 3 :(得分:0)

此示例使用集合中的namedtuple类。我也重写了课程来实现它(它应该仍然适用于你现有的程序)。

另请注意,python通常不使用setter或getter。事实上。您可以直接在程序中设置描述(如您所愿),而不是使用您的setter函数。

import math
from collections import namedtuple

point = namedtuple('point', ['x', 'y', 'z'])

class Point(object):
    def __init__(self, x=0, y=0, z=0, description='TBD'):
        self.point = point(x, y, z)
        self.__description = description

    def __repr__(self):
        return str(self.point)

    def set_point(self, coords):
        self.point = point(coords)

    def get_point(self):
        p = self.point
        return p.x, p.y, p.z

    def distance(self, toPoint):
        p = toPoint.point
        return math.sqrt(
            (self.point.x - p.x)**2 +
            (self.point.y - p.y)**2 +
            (self.point.z - p.z)**2)

    def set_description(self, description):
        # Python generally does not use getters/setters.
        self.description = description

    def get_description(self):
        # Python generally does not use getters/setters.
        return self.description

答案 4 :(得分:0)

另一种方法是将toPoint.PointCoords解压缩到这样的局部变量中:

def Distance(self, toPoint):
    x, y, z = toPoint.PointCoords
    return math.sqrt(
        (self.__x - x)**2 +
        (self.__y - y)**2 +
        (self.__z - z)**2)