Search code examples
pythonfaker

Why does my Program override both Objects?


i am working on a programm to create fakeduplicates, which have some kind of inconsistencies in a specified attribute.

I am using my class "Firma":

class Firma:
    def __init__(self, firma, strasse, plz, ort, telefon):
        self.firma = firma
        [...]

    def getFirma(self):
       return self.firma
        [...]

    def setFirma(self, firma):
      self.firma = firma
        [...]

    def toString(objekt) -> str:
        result = '"' + objekt.getFirma() + '"\t"' + objekt.getStrasse() + '"\t"' + objekt.getOrt() + '"\t"' + objekt.getPlz() + '"\t"' + objekt.getTelefon() + '"'
        return result

Now i wrote this code to test if my method "createSchreibfehler" creates a mistake the way i want it to.

for i in range(100):

    firma = Generator.generateFirma()

    x = firma
    y = firma

    AttributFirma = x.getFirma()
    fehlerString = Szenario.createSchreibfehler(AttributFirma)
    y.setFirma(fehlerString)

    print(Firmendatensatz.Firma.toString(x))
    print(Firmendatensatz.Firma.toString(y))

I get an Output like:

"Bohlnader" "Lachmannstr. 113"  "Bamberg"   "13669" "01991 351660"
"Bohlnader" "Lachmannstr. 113"  "Bamberg"   "13669" "01991 351660"
or 
"Carsetn"   "Seifertring 139"   "Delitzsch" "64621" "(00423) 19090"
"Carsetn"   "Seifertring 139"   "Delitzsch" "64621" "(00423) 19090"
...

(There is a Spelling Mistake in both Strings(x and y)) (to create a Firma i am using the Faker package)

Everything works fine, except that it seems like its overriding my x and y when im using y.setFirma(fehlerString).

Do you guys have an idea why there is a mistake in x and y and not only in my variable x ? I am using Python 3.7.1 in JetBrains PyCharm


Solution

  • You are not creating two independent object by doing

    firma = Generator.generateFirma()
    
    x = firma
    y = firma
    

    x and y are names referencing the the same object-data. Any change you do to x is done on the data that y also references.

    This is a typical beginner error when using mutable objects - mostly seen using lists:

    If you do not need your accessor methods, remove them, they only complicate your structures. You can create a simple clone-ing method that creates an independant instance of your object and use that:

    class Firma:
        def __init__(self, firma, strasse, plz, ort, telefon):
            self.firma = firma
            self.strasse = strasse 
            self.plz = plz
            self.ort = ort
            self.telefon = telefon
    
        def CloneMe(self):
            """Returns a clone of this object as independent copy."""
            return Firma(self.firma,self.strasse,self.plz,self.ort,self.telefon)
    
    
        def __str__(self):
            # default string method so you can simply print() your object-instances
            return f'"{self.firma}"\t"{self.strasse}"\t"{self.plz}"\t"{self.ort}"\t"{  self.telefon}"'
    
    x = Firma("A", "cstr 42", "4444", "NoWhere"," 0123456789")
    
    # clone and change something
    
    y = x.CloneMe()    
    y.ort = "Muenchen"     # no need for get/set methods 
    
    print(x, "=>", id(x))
    print(y, "=>", id(y))
    

    Output (different data, different ids):

    "A" "cstr 42"   "4444"  "NoWhere"   " 0123456789" => 139652937418232   # x
    "A" "cstr 42"   "4444"  "Muenchen"  " 0123456789" => 139652937418288   # y