Python - 迭代完成后变量会恢复到原始值

标签 python iteration overloading

我写了这段代码来说明这个问题。在代码本身下方,您可以看到控制台打印输出。

在我的程序中,Polygon 类对象将顶点坐标存储在指向每个顶点的向量列表中。 Translate() 函数所要做的就是遍历列表中的每个向量并将参数向量添加到每个项目。很简单,对吧?

Vector 类有自己重载的__add__ 函数。

当我编写和测试代码时,我发现该列表的成员仅在我迭代时发生变化。完成后,所有坐标都会恢复为原始值。

发现这个问题后,凭直觉我又做了一个函数——Manual_Translate(),它是手工计算向量分量的(没有调用Vector.__add__)

class Vector():

    def __init__(self, X, Y):
        self.x = X
        self.y = Y

    def __add__(self, Other_Vector):

        return Vector((self.x + Other_Vector.x),(self.y + Other_Vector.y))

class Polygon():

    def __init__(self, point_list):

        self.Points = []

        for item in point_list:
            self.Points.append (Vector(item[0], item[1]))

    def Translate (self, Translation):

        for point in self.Points:
            point += Translation
            print (point.x, point.y)  #printout from the same loop

    def Manual_Translate (self, Translation):

        for point in self.Points:
            point.x += Translation.x
            point.y += Translation.y
            print (point.x, point.y)

    def Report (self):

        for point in self.Points:
            print (point.x, point.y)  #printout from another loop

vertices = [[0,0],[0,100],[100,100],[100,0]]

Square = Polygon (vertices)
print ("A: we used __add__ function")
Square.Translate (Vector(115,139))
print ("")
Square.Report()
print ("\nB: we calculated vector sum by hand")
Square.Manual_Translate (Vector(115,139))
print ("")
Square.Report()

结果: 如果我使用 __add__,值更改会丢失。如果我手动添加矢量 - 它们会留下来。我错过了什么? __add__ 实际上与这个问题有什么关系吗?怎么回事?

A: we used __add__ function
115 139
115 239
215 239
215 139

0 0
0 100
100 100
100 0

B: we calculated vector sum by hand
115 139
115 239
215 239
215 139

115 139
115 239
215 239
215 139

最佳答案

您的问题是因为您的 __add__ 函数正在返回 Polygon 的新实例,而不是实际更改实例的值。

return Vector((self.x + Other_Vector.x),(self.y + Other_Vector.y))

应该改为:

self.x += Other_Vector.x
self.y += Other_Vector.y
return self

正如 Pynchia 指出的那样,这只有效,因为您假设正在调用 += 运算符。为了更好地适应所有类的实现,显式定义 __add____iadd__ 数据模型方法:

  • __add__ 对于 c = b + a 之类的东西应该返回一个新实例,因此您的原始代码本来就没问题。

    <
  • __iadd__ 适用于就地运算符 +=,然后应该像我的代码一样返回自身。

关于Python - 迭代完成后变量会恢复到原始值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34138975/

相关文章:

python - 更新 "default dictionary"中的值而不删除其键

jquery .each 迭代

python - Python 中的一个函数可迭代并发列表以用于方程

c# - 如何在 C# 中遍历类的实例?

c++ - 是否需要重写一个以基类为参数的虚函数?

c# - 通用重载决议

python - 使用 key 的扭曲 ssh 服务器身份验证

python - Django ModelForm 初始不适用于文本区域

python - Python 中的单行 for 循环是如何工作的? [列表理解]

java - 在 Java 中接受不同类型的参数