Python:attributeRor:“Point”对象没有属性“x”

2024-09-28 17:31:25 发布

您现在位置:Python中文网/ 问答频道 /正文

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!')

Tags: selfinputrawdefdescriptioncoordsdistancepoint
3条回答

您可以公开访问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

实际错误是由于访问toPoint.x而导致的,因为您从未定义过该访问,所以该访问不存在。

另一个相关的注意事项是,在属性前面加上双下划线会激活pythonsname mangling特性。实际的属性仍然可以在类之外的my_point._Point__xmy_point._Point__y等处公开访问。

就风格而言,在这种情况下似乎没有任何理由使用名称损坏。此功能的预期用例是为了避免与继承的类发生冲突,而不是真正尝试生成“私有”变量(为此,约定是使用一个下划线来指示属性何时是实现细节)。

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

在Distance()的返回行中,ux而不是x(对于y和z相同),因为Point类的实例没有x,y z属性,但是它们有x,uu y,u 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)

相关问题 更多 >