[英]Python, Avoid overwriting argument to function
I am very new to Python and was surprised to find that this section of my code: 我是Python的新手,很惊讶地发现我的代码的这一部分:
print len(allCommunities[5].boundary)
allCommunities[5].surface = triangularize(allCommunities[5].boundary)
print len(allCommunities[5].boundary)
Outputs this: 输出此:
1310
2
Below is a function I wrote in Processing (a language like Java) and ported into Python. 下面是我在Processing(像Java这样的语言)中编写并移植到Python中的函数。 It does what it is supposed to (triangulate a polygon) but my intention was to pass
inBoundary
for the function to use but not remove elements from allCommunities[5].boundary
. 它做了它应该做的(三角形多边形),但我的目的是传递
inBoundary
以使用函数但不删除所有allCommunities[5].boundary
中的元素。
How should I go about preventing allCommunities[5].boundary
from being modified in the function? 我该如何防止所有
allCommunities[5].boundary
在函数中被修改? On a side note, I would appreciate pointers if I am doing something silly otherwise in the function, still getting used to Python. 附带说明一下,如果我在函数中做其他一些愚蠢的事情,但仍然习惯于Python,我将不胜感激。
def triangularize(inBoundary):
outSurface = []
index = 0;
while len(inBoundary) > 2:
pIndex = (index+len(inBoundary)-1)%len(inBoundary);
nIndex = (index+1)%len(inBoundary);
bp = inBoundary[pIndex]
bi = inBoundary[index]
bn = inBoundary[nIndex]
# This assumes the polygon is in clockwise order
theta = math.atan2(bi.y-bn.y, bi.x-bn.x)-math.atan2(bi.y-bp.y, bi.x-bp.x);
if theta < 0.0: theta += math.pi*2.0;
# If bp, bi, and bn describe an "ear" of the polygon
if theta < math.pi:
inside = False;
# Make sure other vertices are not inside the "ear"
for i in range(len(inBoundary)):
if i == pIndex or i == index or i == nIndex: continue;
# Black magic point in triangle expressions
# http://answers.yahoo.com/question/index?qid=20111103091813AA1jksL
pi = inBoundary[i]
ep = (bi.x-bp.x)*(pi.y-bp.y)-(bi.y-bp.y)*(pi.x-bp.x)
ei = (bn.x-bi.x)*(pi.y-bi.y)-(bn.y-bi.y)*(pi.x-bi.x)
en = (bp.x-bn.x)*(pi.y-bn.y)-(bp.y-bn.y)*(pi.x-bn.x)
# This only tests if the point is inside the triangle (no edge / vertex test)
if (ep < 0 and ei < 0 and en < 0) or (ep > 0 and ei > 0 and en > 0):
inside = True;
break
# No vertices in the "ear", add a triangle and remove bi
if not inside:
outSurface.append(Triangle(bp, bi, bn))
inBoundary.pop(index)
index = (index+1)%len(inBoundary)
return outSurface
print len(allCommunities[5].boundary)
allCommunities[5].surface = triangularize(allCommunities[5].boundary)
print len(allCommunities[5].boundary)
Lists in Python are mutable, and operations such as Python中的列表是可变的,以及诸如的操作
inBoundary.pop
modify them. 修改它们。 The easy solution is to copy the list inside the function:
简单的解决方案是复制函数内的列表:
def triangularize(inBoundary):
inBoundary = list(inBoundary)
# proceed as before
The easiest thing to do would be to make a copy of the argument coming in: 最简单的方法是复制传入的参数:
def triangularize(origBoundary):
inBoundary = origBoundary[:]
Then the rest of your code can stay the same. 然后你的其余代码可以保持不变。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.