1

重複の可能性:
Pythonの「驚き最小の原則」:可変のデフォルト引数

私はPythonでMailSnakeを使用しています。これは、MailChimpAPIのラッパーです。

今、私は、私たちが持っているサブスクライバーのリストをプルするために書いた関数に対して、いくつかの奇妙な振る舞いをしています。これは私が使用しているコードです:

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'

したがって、この関数は、指定されたリストからすべてのメンバーをプルするまで再帰的に実行されます。

しかし、私が気付いたのは、変数unsubsがどんどん大きくなっているように見えることです。関数return_membersが異なるリストIDで呼び出されると、(1つの特定のリストだけでなく)これまでに呼び出したすべてのリストの電子メールの融合が得られます。

明示的に新しい配列を与えるreturn_members('subscribed'、id、[])を呼び出すと、問題ありません。しかし、なぜこれを行う必要があるのか​​わかりません。別のリストIDで関数を呼び出しているかのように、再帰的に実行されておらず、members変数を指定していないため、デフォルトで[]になります。

これはPythonの癖かもしれないと思います、または私はちょうど何かを逃しました!

4

2 に答える 2

2

MartjinによるリンクされたSOの悪名高い質問は、アンダースコアの問題を理解するのに役立ちますが、これを整理するには、次のループを作成できます

for item in temp_list['data']:  # Add latest pulled data to our list
    members.append(item)

よりpythonicバージョンに

members = members + temp_list['data'] # Add latest pulled data to our list

この小さな変更により、パラメータとして渡されたインスタンスとは異なるインスタンスで作業していることが保証されます。return_members

于 2012-12-29T18:42:24.050 に答える
1

交換してみてください:

def return_members (status, list_id, members = [], start = 0, limit = 15000, done = 0):

と:

def return_members (status, list_id, members = None, start = 0, limit = 15000, done = 0):
    if not members: members = []
于 2012-12-29T18:39:35.137 に答える