scientificCompNoob scientificCompNoob - 1 month ago 5
Python Question

Strange Behavior....Python class bound method retaining keyword arguments after call

I have a simple data model class for a GUI. In this class I have a addPnt method that attaches a timestamp if one is not passed through a keyword argument "timeDict". I expected that the default value ({}) would be set to timeDict at the start of every call to addPnt. However, while debuging, timeDict retains the values from the initial call to addPnt?!?! See code below

class LastTSDict(dict):
def __getitem__( self, name ):
try:
return super( LastTSDict, self ).__getitem__( name )
except KeyError:
self.__setitem__(name,timestamp.getTimestamp())
return self.__getitem__( name )

class DataElementDict(dict):
def __init__(self,maxLen):
self.maxLen=maxLen
self.lastTS=LastTSDict()
def __getitem__( self, name ):
try:
return super( DataElementDict, self ).__getitem__( name )
except KeyError:
if name==0:
self.__setitem__(name,defaultdict(partial(defaultdict,partial(deque, maxlen=self.maxLen))))
else:
self.__setitem__(name,defaultdict(partial(defaultdict,partial(deque, maxlen=self.maxLen/8))))
return self.__getitem__( name )

class Model(object):
def __init__(self,maxLen=8192,extPeriods=[5,60,300,900,3600,86400]):
self.DATA=DataElementDict(maxLen)
self.extPeriods=extPeriods

def addPnt(self,key,value,timeDict={}):
try:
pdb.set_trace()
if 'ts' not in timeDict.keys():
timeDict['ts']=timestamp.getTimestamp()
if 'tu' not in timeDict.keys():
timeDict['tu']=timestamp.unixTime(timeDict['ts'])
self.DATA[0][key]['v'].append(value)
for keyt in timeDict.keys():
self.DATA[0][key][keyt].append(timeDict[keyt])


whats going on here?

Answer

The value of default arguments is only created once at the defintion time of the function.

def addPnt(self,key,value,timeDict={}):

This means that every call uses the same dictionary object. Not a new one for each call.

To fix this use:

def addPnt(self,key,value,timeDict=None):
    if timeDict is None:
        timeDict = {}
Comments