Думаю, об этом будет легче подумать, если вы положите преобразование в начало, разрешите рекурсивным вызовам проходить ObjectId
и вернуть преобразованные строки напрямую с помощью функции, а не пытаться преобразовать внутри циклов в функция. Затем вы можете просто передать значение в рекурсию и получить строку обратно.
Что-то вроде:
from datetime import datetime
def clean_dict_helper(d):
if isinstance(d, ObjectId) or isinstance(d, datetime):
return str(d)
if isinstance(d, list): # For those db functions which return list
return [clean_dict_helper(x) for x in d]
if isinstance(d, dict):
for k, v in d.items():
d.update({k: clean_dict_helper(v)})
# return anything else, like a string or number
return d
Вызов:
clean_dict_helper({
1: {
1: ObjectId('5e0e83a6d0fbe7238c960ea0'),
2: [ObjectId('5e0e83a6d0fbe7238c960ea0'), ObjectId('5e0e83a6d0fbe7238c960ea0')],
3: datetime(2020, 1, 1),
4: [{1: ObjectId('5e0e83a6d0fbe7238c960ea0')}],
5: 'test'
},
2: [ObjectId('5e0e83a6d0fbe7238c960ea0'), ObjectId('5e0e83a6d0fbe7238c960ea0')]
})
Затем вернет:
{1: {1: '5e0e83a6d0fbe7238c960ea0',
2: ['5e0e83a6d0fbe7238c960ea0', '5e0e83a6d0fbe7238c960ea0'],
3: '2020-01-01 00:00:00',
4: [{1: '5e0e83a6d0fbe7238c960ea0'}],
5: 'test'},
2: ['5e0e83a6d0fbe7238c960ea0', '5e0e83a6d0fbe7238c960ea0']}
Кроме того, поскольку вы создаете новый список с пониманием, может иметь смысл возвращать новый dict, а не мутировать переданное значение с чем-то вроде:
if isinstance(d, dict):
return {k:clean_dict_helper(v) for k, v in d.items() }