类的python元素复制了accros新实例

时间:2017-05-04 13:15:02

标签: python attributes copy instance

我有一个名为KSlamComp的班级,用于读取文件中的数字并将其放在两个属性gt_rawslam_raw

class KSlamComp:
    def __init__(self, forward_nodes_lookup = 1, backward_nodes_lookup = 0, slam_input_raw = data.Data(), gt_input_raw = data.Data()):
        self.slam_raw = slam_input_raw
        self.gt_raw = gt_input_raw
        self.nb_node_forward = forward_nodes_lookup
        self.nb_node_backward = backward_nodes_lookup

    def read(self, file_name):
        assert(len(self.slam_raw.posetime) == 0)
        f = open(file_name, 'r')
        for line in f:
            print("line")
            assert len(line.split()) == 8

            slampose = data.Pose(data.Point( float(line.split()[0]), float(line.split()[1] )),  float(line.split()[2]))
            gtpose = data.Pose(data.Point( float(line.split()[4]), float(line.split()[5] )),  float(line.split()[6]))

            self.slam_raw.posetime.append( (slampose, float(line.split()[3]) ) )
            self.gt_raw.posetime.append( (gtpose, float(line.split()[7]) ) )


    def printraw(self):
        print("Printing Raw data")
        for x in range(0, len(self.slam_raw.posetime)):
            print(str(self.slam_raw.posetime[x][0].getPosition().x) + " " \
                + str(self.slam_raw.posetime[x][0].getPosition().y) + " " \
                + str(self.slam_raw.posetime[x][0].getOrientation()) + " " \
                + str(self.slam_raw.posetime[x][1]) + " " + \
                  str(self.gt_raw.posetime[x][0].getPosition().x) + " " \
                + str(self.gt_raw.posetime[x][0].getPosition().y) + " " \
                + str(self.gt_raw.posetime[x][0].getOrientation()) + " " \
                + str(self.gt_raw.posetime[x][1]))
        print("\n")

Data只是那些行

class Data:
    def __init__(self):
        #Tuple with pose and time 
        self.posetime = list()

现在我有了这个测试文件

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from kslamcomp import data
from kslamcomp import kslamcomp

def main():
    # parse command line options
    d = kslamcomp.KSlamComp(1, 0)
    d.read("data_files/shifted.txt")
    d.printraw()
    d.print()

    d_invert = kslamcomp.KSlamComp()
    d_invert.printraw()
    d.printraw()

if __name__ == "__main__":
    main()

我的理解是d_invert是一个新对象KSlamComp,所有属性都初始化为默认值。特别是,self.slam_rawself.gt_raw是具有空列表的空Data个对象。无论何时我运行这个程序,我都有

$ python3 test_sanity.py 
line
line
line
line
Printing Raw data
1.0 1.0 1.0 2.0 3.0 3.0 3.0 6.0
5.0 5.0 5.0 6.0 8.0 8.0 7.1 14.0
9.0 9.0 9.0 10.0 11.0 11.0 11.0 2.0
13.0 13.0 13.0 14.0 15.0 15.0 15.0 10.0


Printing Raw data
1.0 1.0 1.0 2.0 3.0 3.0 3.0 6.0
5.0 5.0 5.0 6.0 8.0 8.0 7.1 14.0
9.0 9.0 9.0 10.0 11.0 11.0 11.0 2.0
13.0 13.0 13.0 14.0 15.0 15.0 15.0 10.0


Printing Raw data
1.0 1.0 1.0 2.0 3.0 3.0 3.0 6.0
5.0 5.0 5.0 6.0 8.0 8.0 7.1 14.0
9.0 9.0 9.0 10.0 11.0 11.0 11.0 2.0
13.0 13.0 13.0 14.0 15.0 15.0 15.0 10.0

虽然我认为第二个打印件是空的,但它似乎包含在第一个KSlamComp对象中读取的数据。

为什么slef.gt_rawSelf.slam_raw在两个对象中都是相同的对象?如果我通过调用d_invert = kslamcomp.KSlamComp(0, 1, data.Data(), data.Data())“手动”初始化它们似乎可行,但我认为默认参数是相同的。

1 个答案:

答案 0 :(得分:2)

您不应将可变对象用作函数的默认值,因为默认值存储在函数对象中。 我可能会写

class KSlamComp:
    def __init__(..., slam_input_raw = None, gt_input_raw = None, ...) 
        self.slam_raw = slam_input_raw or data.Data()
        self.gt_stuff = gt_input_raw or data.Data()