我想实现一个用于表示线串的类。我有一个名为“Point”的课程 表示具有2个坐标的点,我想用它来存储内部顶点 线串。 我想出了这段代码:
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
class LineString(Point):
def __init__(self, point):
self.point = point
但我不知道如何在线串中显示多个点 支持像:
这样的线串lin = LineString((1, 1), (0, 2), (3,6))
我不知道线串中可能出现的点数。 新代码:
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
class LineString(Point):
def __init(self, *points):
#~ self.points=points
self.points = []
for point in points:
if not isinstance(point, Point):
point = Point(*point)
self.points.append(point)
def length(self):
L = len(self.points)
return L
if __name__ == '__main__':
# Tests for LineString
# ===================================
lin1 = LineString((1, 1), (0, 2))
assert len(lin1.points) == sqrt(2.0)
答案 0 :(得分:1)
为您的构造函数提供一个带*argumentname
的变量参数:
class LineString(Point):
def __init__(self, *points):
self.points = points
您可以根据需要将元组转换为Point()
个实例:
class LineString(Point):
def __init__(self, *points):
self.points = []
for point in points:
if not isinstance(point, Point):
point = Point(*point)
self.points.append(point)
在这两种情况下,self.points
现在都是Python list
对象。请注意在Point(*point)
调用中使用镜像语法; point
元组的元素作为单独的参数应用于Point.__init__()
方法,将(1, 1)
元组作为x
和y
的两个参数传递。< / p>
现在您可以使用以下任一方式构建一个行字符串:
lin = LineString((1, 1), (0, 2), (3,6))
或
lin = LineString(Point(1, 1), Point(0, 2), Point(3,6))
演示:
>>> lin = LineString((1, 1), (0, 2), (3,6))
>>> len(lin.points)
3
>>> lin.points[0]
<__main__.Point object at 0x108988fd0>
>>> lin.points[0].x, lin.points[0].y
(1, 1)
答案 1 :(得分:1)
行不是点,也不是行的字符串。 Liskov Substitution Principle表明应始终可以将派生类的实例替换为其父类之一。请考虑以下代码:
def move_point(point, xdist, ydist):
return Point(point.x + xdist, point.y + ydist)
p = Point(3, 4)
q = move_point(p, 5, 6)
assert q.x == 8 and q.y == 10
r = LineString((2, 3), (5, 4), (8, 6))
s = move_point(r, 5, 6) # ???
s
可能是什么?一串行的(x, y)
坐标是什么?
解决这个问题的方法就是不从Point派生LineString。相反,代码看起来应该是这样的:
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
... # see implementation details @ http://docs.python.org/2.7/library/itertools.html#recipes
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y
def distance(point1, point2):
... # needs implementing
class Line(object):
def __init__(self, a, b): # a and b must be Points
self.a = a
self.b = b
@property
def length(self):
return distance(self.a, self.b)
class LineString(object):
def __init(self, *points):
# We assume that points consists only of proper Point instances.
# If people pass invalid arguments, it's their problem.
self.points = points
@property
def length(self):
return sum(distance(p1, p2) for p1, p2 in pairwise(self.points))
if __name__ == '__main__':
lin1 = LineString((1, 1), (0, 2))
assert lin1.length == sqrt(2.0)
此外,浮点运算有时会产生奇怪的结果:
>>> .1 + .2 == .3
False
>>> .1 + .2
0.30000000000000004
有关说明,请参阅http://floating-point-gui.de。