Possible Duplicate:
“Least Astonishment” in Python: The Mutable Default Argument
I’m using the MailSnake in Python, which is a wrapper for the MailChimp API.
Now I’m getting some curious behaviour for a function I’ve written to pull lists of subscribers we have. This is the code I’m using:
from mailsnake import MailSnake
from mailsnake.exceptions import *
ms = MailSnake('key here')
def return_members (status, list_id, members = [], start = 0, limit = 15000, done = 0):
temp_list = ms.listMembers(status=status, id=list_id, start=page, limit=limit, since='2000-01-01 01:01:01')
for item in temp_list['data']: # Add latest pulled data to our list
members.append(item)
done = limit + done
if done < temp_list['total']: # Continue if we have yet to
start = start + 1
if limit > (temp_list['total'] - done): # Restrict how many more results we get out if are on the penultimate page
limit = temp_list['total'] - done
print 'Making another API call to get complete list'
return_members(status, list_id, members, page, limit, done)
return members
for id in lists:
unsubs = return_members('subscribed',id)
for person in unsubs:
print person['email']
print 'Finished getting information'
So this function runs recursively until we have pulled all members from a given list.
But what I’ve noticed is that the variable unsubs seems to just get bigger and bigger. In that when the function return_members is called with different list ids, I get an amalgamation of the emails of every list I have called so far (rather than just one particular list).
If I call return_members(‘subscribed’, id, []) which explicitly gives it a fresh array then it’s fine. But I don’t see why I need to do this, as if I am calling the function with a different list ID, it’s not running recursively and since I haven’t specificed the members variable, it defaults to []
I think this may be a quirk of python, or I’ve just missed something!
The linked SO infamous question by Martjin would help you understand the underline issue, but to get this sorted out you can write the following loop
to a more pythonic version
this small change would ensure that you are working with an instance different from the one passed as the parameter to
return_members