Python 3, новый для кодирования и Python. я создал словарь класса со значениями по умолчанию, затем попытался создать вложенный словарь на основе этого словаря класса и столкнулся с неожиданным поведением:
class User:
def __init__(self, *, name=None, age=None, hobbies=[]):
self.name = name
self.age = age
self.hobbies = hobbies
counter = 0
class_dict = {}
# building the nested dicts with default values
for num in range(0, 3):
"""
1. referencing "User.__init__.__kwdefaults__"
vs writting the actual dict directly into the nested dict
2. {"name": None, "age": None, "hobbies": []}
"""
class_dict.update({f"key_{num}": User.__init__.__kwdefaults__})
# class_dict.update({f"key_{num}": {"name": None, "age": None, "hobbies": []}})
print("Blue print: " + str(class_dict))
# updating values in the nested dicts
for x in range(0, 3): # simplified loop
dict_key = "key_" + str(counter)
try:
if 1 < 2: # simplified if check
class_dict[dict_key]["name"] = "updated" + str(counter)
print("inside loop: " + str(class_dict))
counter = counter + 1
except:
continue
print("<<< final result: " + str(class_dict) + ">>>") # end-result
версия User.init.kwdefaults обновит правильные вложенные ключи dicts внутри цикла, как и ожидалось, но в конечном результате все 3 вложенных ключа имени dicts сохранят update2 как значение. то, что когда-либо изменялось в последней итерации цикла, изменяется во всех вложенных словарях.
фактическая версия dict {name: None, age: None, hobbies: []} также обновляет правильные вложенные ключи dict внутри цикла, как и ожидалось. однако конечный результат здесь для ключа имени во вложенном dict 1 сохраняет значение updated0, во вложенном dict 2 updated1 и во вложенном 2 updated2.
конечный результат 2. - это то, к чему я стремился, и мне потребовалось некоторое время, чтобы найти проблему. я не понимаю, почему обе версии ведут себя одинаково внутри цикла, но имеют разные конечные результаты. есть ли метод dunder/magic для ссылки на словарь классов и получения версии 2. в качестве конечного результата?
User.__init__.__kwdefaults__
. Вы просто продолжаете добавлять этот один объект снова и снова. - person MisterMiyagi   schedule 03.09.2020User.__init__.__kwdefaults__
использует значения по умолчаниюUser.__init__
, это запутанный случай изменяемых значений по умолчанию для функций. - person MisterMiyagi   schedule 03.09.2020