🙄
【Python】dict.copy()したのに中身が上書きされてしまった!
概要
SlackのAPIを利用して2種類の情報をそれぞれ別のチャンネルに通知するためのプログラムで両方のチャンネルに同じ情報が出てしまった。
通知したい内容の部分以外はSlackAPIのためのデータの構成は同一であるため、以下のように記載。
バージョン情報
今回の知見にバージョンはあまり関係はないが、念のため。
- Python3.9
- AWS Lambda
スクリプト
default = {
'username': '',
'blocks': [
{
'type': 'section',
'text': {
'type': 'mrkdwn',
# 'text': '通知したい内容'
}
}
]
}
slack1 = default.copy()
slack1['blocks'][0]['text']['text'] = 'hogehoge'
slack2 = default.copy()
slack2['blocks'][0]['text']['text'] = 'fugafuga'
この後、slack1, slack2を使用してrequestしたところ、両チャンネルにfugafuga
と通知されてしまった。
ログにオブジェクトIDを出力しても、問題無く別のIDが出力されるため原因が分からず。
logger.info(id(default)) # XXXXXXXXXX0
logger.info(id(slack1)) # XXXXXXXXXX1
logger.info(id(slack2)) # XXXXXXXXXX2
結論
今回のスクリプトではdict内にlistが含まれており、dictは別のオブジェクトとして存在したものの、dict内のlistが同じものであったことが原因だった。
copy()が浅いコピーであったために、発生。
deepcopy()にてdictを再帰的にコピーすることで解決。
import copy
default = {省略}
slack1 = copy.deepcopy(default)
slack1['blocks'][0]['text']['text'] = 'hogehoge'
slack2 = copy.deepcopy(default)
slack2['blocks'][0]['text']['text'] = 'fugafuga'
Discussion