1

I wrote this simple python program to help me with a bug in another program. It clearly illustrates the problem.

import copy

class Obj(object):
    def __init__(self, name):
        self.name = name

def one(o):
    print("1: o.name:", o.name) # "foo"
    obackup = copy.deepcopy(o) 
    o.name = "bar"
    print("2: o.name:", o.name) # "bar"
    print("3: obackup.name:", obackup.name) # "foo"
    o = obackup
    print("4: o.name:", o.name) # "foo"

def two(o):
    print("5: o.name:", o.name) # "bar"!

def main():
    o = Obj("foo")
    one(o)
    two(o)

main()

My guess is that o is being overwritten somehow as a local variable to the function one(). But I have no idea how to fix that.

Nick T
  • 25,754
  • 12
  • 83
  • 121
Violet
  • 507
  • 4
  • 15

2 Answers2

2

Forget that the copy module exists, it almost never is needed and often produces surprising results.

As soon as you say o = obackup in one() you have created a new binding for the formal argument which then goes out of scope after print('4...

msw
  • 42,753
  • 9
  • 87
  • 112
0

o is a local variable to the one() so this problem cannot be fixed elegantly. But you could use some reference/pointer which you pass to the one() and two().

Simulating Pointers in Python

Community
  • 1
  • 1
phadej
  • 11,947
  • 41
  • 78
  • Thanks. It's good to know that there is no easy fix. I've fixed it now by having all relevant functions return the object. – Violet Aug 26 '10 at 21:24
  • It would be much better to restructure the code (as mentioned, returning the object works well) than to try to simulate pointers. – habnabit Aug 26 '10 at 22:37