Bug caused by using changeable value as the default in "python method overload"​

  sonic0002        2019-03-11 08:52:52       3,076        0    

In python we can set the passed in parameter's default value to make the function has the same running feature as the method overload in Java.

Define a function like this:

def testFunction(self, param1, param2=None, param3=None):

Normally we use "None" as the parameter's default value. We can also use str/bool as the default value, but is it OK we use empty list [] as its default value?

This is our test program:

""" A test program using empty list as the passed-in parameter's
    default value.
"""
class TestFunc(object):

    def __init__(self, id, parm = []):
        self.ObjId = id
        self.parm = parm
    
    def addNewParm(self, newParm):
        self.parm.append(newParm)

    def printAllParm(self):for item in self.parm:
            print(item)

obj_A = TestFunc('obj_a')
obj_A.addNewParm('A')
obj_A.addNewParm('B')
print(str(obj_A.ObjId)+':')
obj_A.printAllParm()

print('-------------------------')
obj_B = TestFunc('obj_b')
obj_B.addNewParm('C')
obj_B.addNewParm('D')
print(str(obj_B.ObjId)+':')
obj_B.printAllParm()
print ('================')
print ("obj_A parm reference id:" +str(id(obj_A.parm)))
print ("obj_B parm reference id:" +str(id(obj_B.parm)))

When we run it, the result shows:

The value we added in object A also appeared in the object B. And the object A's parm and object B's parm shared same memory id. When this happened, it is difficult for us to find the program's problem during debugging.

-------------------------------------------------------------------------

The reason caused this problem is the python's value assignment feature in memory management . In C++ if we do this:

a = 1; b = a; b =2;

In C, 2 memory location will be arranged for the two parameters and then the value will be put in to the memory like this:

But if we do the same thing in python, python will fill a memory position with value 1 then point a and b to that position. When we change b's value to 2. Value 2 will be fill in another memory position, then point b to that new memory address.

 

So if we use a changeable value such as empty list [] as the default value, the two objects' parameter will point to the same memory address which hold the [] at the init process. And that is the reason why we got the unexpected running result. 

Note: This post is authorized to republish here by Yuancheng Liu, Systems Software Engineer at ZycraftUSV.PTE.LTD. Original post is here.

PYTHON 

       

  RELATED


  0 COMMENT


No comment for this article.



  RANDOM FUN

HR gets an HR