2017-05-04 1 views
0

je classe nommée KSlamComp qui a lu les numéros à partir d'un fichier et le mettre dans deux attributs gt_raw et slam_rawélément de python de classe copié Accros de nouvelles instances

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") 

Le Data est simplement quelque chose le long de ces lignes

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

maintenant, j'ai ce fichier de test

#!/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() 

Ma compréhension était que d_invert est un nouvel objet KSlamComp avec tous les attributs initialisés à leur valeur par défaut. En particulier, self.slam_raw et self.gt_raw sont vides Data objets avec des listes vides. Hoever quand je lance ce programme, je

$ 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 

Alors que je pensais que la deuxième impression whould été vide, il semble contenir les données qui ont été lues dans le premier objet KSlamComp.

Pourquoi slef.gt_raw et Self.slam_raw le même objet à la fois l'objet? Si je les ai initialisés "manuellement" en appelant d_invert = kslamcomp.KSlamComp(0, 1, data.Data(), data.Data()) cela semble fonctionner mais je pensais qu'avoir le paramètre par défaut était le même.

+1

Un célèbre gotcha: Utilisation de structures de données mutables comme valeur par défaut – Maresh

Répondre

2

Vous ne devriez pas utiliser des objets mutables comme paramètres par défaut de la fonction, car les valeurs par défaut sont stockées dans un objet de fonction. J'écrirais probablement

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()