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!')
答案 0 :(得分:2)
实际错误是由于访问toPoint.x
而导致的,因为您从未对其进行定义,因此不存在。
在相关说明中,使用双下划线添加属性会激活pythons name mangling功能。实际属性仍可在课堂外my_point._Point__x
,my_point._Point__y
等公开访问。
作为一种风格问题,在这种情况下似乎没有任何理由使用名称修改。此功能的预期用例是为了避免与继承的类冲突,它并不是真的想要使私有&#34;私有&#34;变量(为此,约定是使用单个下划线来指示属性何时是实现细节)。
在您的情况下,我认为您应该通常x
,y
等来命名(和访问)属性。在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类的x
,y
和z
属性。如果您希望客户端能够读取但不能写入,则可以使用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)