函数中的局部变量未初始化并记住以前的函数调用
Local variable in function is not initialized and remembers previous function calls
我是 Python 编程新手,在面向对象编程方面几乎没有经验。我遇到了一个我无法真正理解的问题。我知道问题出在哪里,但我不知道为什么会出现。由于我想了解面向对象编程的基础知识,因此切换到现有库对我来说不是一个选择。
所以这就是我想要做的:
我有几个只包含二维坐标(x 和 y)的 *.csv 文件。我逐行读取文件,并从每对 x 和 y 创建一个对象 "Point2D"。然后我将此 "Point2D" 添加到存储在另一个对象 "PointCloud".
中的列表
奇数部分来了:
如果我只打开一个 *.csv 文件,函数 "getPointCloudFromCam2Meas" 工作正常。如果我依次打开两个文件,函数的第二次调用 returns 第一个点云 + 第二个点云(附加),即使局部变量 "ptc" 被初始化为一个新的 "PointCloud"每次调用。
为什么程序会这样?
# -*- coding: iso-8859-1 -*-
import numpy as np
import os
class Point2D:
'''A Point in 2-dimensional space.
Attributes:
idx: The index of the Point.
x: The x-coordinate of the Point.
y: The y-coordinate of the Point.
'''
count = 0
def __init__(self, x, y):
self.idx = Point2D.count
self.x = x
self.y = y
Point2D.count += 1
def displayCoords(self):
print("My coordinates are {}, {}".format(self.x, self.y))
def displayIndex(self):
print("My index is {}".format(self.idx))
class PointCloud:
'''A Point Cloud defined by x-y-coordinate tuples.
Attributes:
name: The name of the point cloud.
size: The number of points within the point cloud.
center: The center of gravity of the point cloud as a Point2D.
points: An unsorted list of the Point2D objects that form the PointCloud object
'''
count = 0
points = list()
def __init__(self):
PointCloud.count += 1
def addPoint(self, Point2D):
self.points.append(Point2D)
def displayPointCoords(self):
for point in self.points:
point.displayCoords()
def displayPointIdx(self):
for point in self.points:
point.displayIndex()
def displayPointCount(self):
print("I contain {} points.".format(len(self.points)))
def getXCoords(self):
xCoords = list()
for point in self.points:
xCoords.append(point.x)
return xCoords
def getYCoords(self):
yCoords = list()
for point in self.points:
yCoords.append(point.y)
return yCoords
def getCenter(self):
xCalc = np.sum(self.getXCoords())/len(self.points)
yCalc = np.sum(self.getYCoords())/len(self.points)
center = Point2D(xCalc,yCalc)
return center
def getPointCloudFromCam2Meas(File):
'''Returns a point cloud object that is read from the *.csv file "File"
The *.csv files have to be exported from the Cam2Measure Software.'''
f = open(File)
k = 0
ptc = PointCloud()
line = f.readline()
while len(line) != 0:
linefrag = line.split(";")
# first line is the headerline, so skip it
if k > 0:
x = float(linefrag[3])
y = float(linefrag[4])
pt = Point2D(x, y)
ptc.addPoint(pt)
line = f.readline()
k += 1
f.close()
return ptc
# Main Program
File2 = "Testfile2.csv"
print("Creating point cloud from file \"{}\"".format(File2))
lvPointCloud2 = getPointCloudFromCam2Meas(File2)
lvPointCloud2.getCenter().displayCoords()
lvPointCloud2.displayPointCount()
File3 = "Testfile3.csv""
print("Creating point cloud from file \"{}\"".format(File3))
lvPointCloud3 = getPointCloudFromCam2Meas(File3)
lvPointCloud3.getCenter().displayCoords()
lvPointCloud3.displayPointCount()
Testfile2.csv
Aktiviert;Merkmal;ID;x;y;z;i;j;k;Abweichung von bester Passform;Geräteposition;Messsonde;Gerätename
Ausgewählt;FATre ID31396 Innen01;1;697.652;-1009.629;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen01;2;696.667;-1010.01;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen01;3;695.621;-1010.367;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen01;4;694.589;-1010.682;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen01;5;693.561;-1010.955;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen01;6;692.568;-1011.183;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen01;7;691.479;-1011.394;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen01;8;690.377;-1011.561;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen01;9;689.283;-1011.687;0;;;;;Geräteposition 1;3;P08-02-05-21552
Testfile3.csv
Aktiviert;Merkmal;ID;x;y;z;i;j;k;Abweichung von bester Passform;Geräteposition;Messsonde;Gerätename
Ausgewählt;FATre ID31396 Innen02;1;379.598;-866.472;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen02;2;378.762;-867.039;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen02;3;377.882;-867.628;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen02;4;377.05;-868.199;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen02;5;376.123;-868.819;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen02;6;375.293;-869.388;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen02;7;374.461;-869.952;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen02;8;373.561;-870.56;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen02;9;372.723;-871.125;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen02;10;371.797;-871.756;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen02;11;370.811;-872.418;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen02;12;369.929;-873.015;0;;;;;Geräteposition 1;3;P08-02-05-21552
Ausgewählt;FATre ID31396 Innen02;13;368.989;-873.64;0;;;;;Geräteposition 1;3;P08-02-05-21552
在class PointCloud:
您将点声明为 class 变量:
points = list()
然后 PointCloud 的每个实例共享 points
有时这是需要的行为,但通常不是在实例之间共享数据的 OO 方式。
This Python2 tutorial 对 class 与实例变量进行了很好的介绍。
我是 Python 编程新手,在面向对象编程方面几乎没有经验。我遇到了一个我无法真正理解的问题。我知道问题出在哪里,但我不知道为什么会出现。由于我想了解面向对象编程的基础知识,因此切换到现有库对我来说不是一个选择。
所以这就是我想要做的: 我有几个只包含二维坐标(x 和 y)的 *.csv 文件。我逐行读取文件,并从每对 x 和 y 创建一个对象 "Point2D"。然后我将此 "Point2D" 添加到存储在另一个对象 "PointCloud".
中的列表奇数部分来了: 如果我只打开一个 *.csv 文件,函数 "getPointCloudFromCam2Meas" 工作正常。如果我依次打开两个文件,函数的第二次调用 returns 第一个点云 + 第二个点云(附加),即使局部变量 "ptc" 被初始化为一个新的 "PointCloud"每次调用。
为什么程序会这样?
# -*- coding: iso-8859-1 -*-
import numpy as np
import os
class Point2D:
'''A Point in 2-dimensional space.
Attributes:
idx: The index of the Point.
x: The x-coordinate of the Point.
y: The y-coordinate of the Point.
'''
count = 0
def __init__(self, x, y):
self.idx = Point2D.count
self.x = x
self.y = y
Point2D.count += 1
def displayCoords(self):
print("My coordinates are {}, {}".format(self.x, self.y))
def displayIndex(self):
print("My index is {}".format(self.idx))
class PointCloud:
'''A Point Cloud defined by x-y-coordinate tuples.
Attributes:
name: The name of the point cloud.
size: The number of points within the point cloud.
center: The center of gravity of the point cloud as a Point2D.
points: An unsorted list of the Point2D objects that form the PointCloud object
'''
count = 0
points = list()
def __init__(self):
PointCloud.count += 1
def addPoint(self, Point2D):
self.points.append(Point2D)
def displayPointCoords(self):
for point in self.points:
point.displayCoords()
def displayPointIdx(self):
for point in self.points:
point.displayIndex()
def displayPointCount(self):
print("I contain {} points.".format(len(self.points)))
def getXCoords(self):
xCoords = list()
for point in self.points:
xCoords.append(point.x)
return xCoords
def getYCoords(self):
yCoords = list()
for point in self.points:
yCoords.append(point.y)
return yCoords
def getCenter(self):
xCalc = np.sum(self.getXCoords())/len(self.points)
yCalc = np.sum(self.getYCoords())/len(self.points)
center = Point2D(xCalc,yCalc)
return center
def getPointCloudFromCam2Meas(File):
'''Returns a point cloud object that is read from the *.csv file "File"
The *.csv files have to be exported from the Cam2Measure Software.'''
f = open(File)
k = 0
ptc = PointCloud()
line = f.readline()
while len(line) != 0:
linefrag = line.split(";")
# first line is the headerline, so skip it
if k > 0:
x = float(linefrag[3])
y = float(linefrag[4])
pt = Point2D(x, y)
ptc.addPoint(pt)
line = f.readline()
k += 1
f.close()
return ptc
# Main Program
File2 = "Testfile2.csv"
print("Creating point cloud from file \"{}\"".format(File2))
lvPointCloud2 = getPointCloudFromCam2Meas(File2)
lvPointCloud2.getCenter().displayCoords()
lvPointCloud2.displayPointCount()
File3 = "Testfile3.csv""
print("Creating point cloud from file \"{}\"".format(File3))
lvPointCloud3 = getPointCloudFromCam2Meas(File3)
lvPointCloud3.getCenter().displayCoords()
lvPointCloud3.displayPointCount()
Testfile2.csv
Aktiviert;Merkmal;ID;x;y;z;i;j;k;Abweichung von bester Passform;Geräteposition;Messsonde;Gerätename Ausgewählt;FATre ID31396 Innen01;1;697.652;-1009.629;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen01;2;696.667;-1010.01;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen01;3;695.621;-1010.367;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen01;4;694.589;-1010.682;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen01;5;693.561;-1010.955;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen01;6;692.568;-1011.183;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen01;7;691.479;-1011.394;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen01;8;690.377;-1011.561;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen01;9;689.283;-1011.687;0;;;;;Geräteposition 1;3;P08-02-05-21552
Testfile3.csv
Aktiviert;Merkmal;ID;x;y;z;i;j;k;Abweichung von bester Passform;Geräteposition;Messsonde;Gerätename Ausgewählt;FATre ID31396 Innen02;1;379.598;-866.472;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen02;2;378.762;-867.039;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen02;3;377.882;-867.628;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen02;4;377.05;-868.199;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen02;5;376.123;-868.819;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen02;6;375.293;-869.388;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen02;7;374.461;-869.952;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen02;8;373.561;-870.56;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen02;9;372.723;-871.125;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen02;10;371.797;-871.756;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen02;11;370.811;-872.418;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen02;12;369.929;-873.015;0;;;;;Geräteposition 1;3;P08-02-05-21552 Ausgewählt;FATre ID31396 Innen02;13;368.989;-873.64;0;;;;;Geräteposition 1;3;P08-02-05-21552
在class PointCloud:
您将点声明为 class 变量:
points = list()
然后 PointCloud 的每个实例共享 points
有时这是需要的行为,但通常不是在实例之间共享数据的 OO 方式。
This Python2 tutorial 对 class 与实例变量进行了很好的介绍。