复制 class dict 变量 wizhout 继承
Copy class dict variable wizhout inheritance
我有简单的 class 和 default_model 像这样:
class User(BaseModel):
class Meta:
collection = db.client.users
default_model = {
'cooldowns': {
'bonus': 0,
'transfer': 0,
}
}
如何复制 Meta.default_model 而不将其链接到 class 本身?也就是说,命令是一次性的,而不是从 class 本身继承的。我已经尝试了两次尝试,但它们都与 class 相关联(
#第一次尝试
model = {"user_id": 1}
for k, v in cls.Meta.default_model.items():
if k not in model:
model[k] = v
#第二次尝试
model = {"user_id": 1} | cls.Meta.default_model.copy()
我的意思是:
class User:
class Meta:
default_model = {
"cooldowns": {
"bonous": 0
}
}
model = {}
for k, v in User.Meta.default_model.items():
model[k] = v
# It changes User.Meta.default_model
model['cooldowns']['bonous'] = 1
print(User.Meta.default_model)
我相信你要找的是deepcopy
from copy import deepcopy
class User:
class Meta:
default_model = {
"cooldowns": {
"bonus": 0,
"transfer": 0,
}
}
print(User.Meta.default_model)
new = deepcopy(User.Meta.default_model)
new["cooldowns"]["bonus"] = 5
print(new) # bonus now 5
print(User.Meta.default_model) # bonus still 0
这给出了输出:
{'cooldowns': {'bonus': 0, 'transfer': 0}}
{'cooldowns': {'bonus': 5, 'transfer': 0}}
{'cooldowns': {'bonus': 0, 'transfer': 0}}
您看到此行为(在 class 中更改的值也在新字典 model
中更改),因为您有一个嵌套字典。 cooldowns
的值本身就是一个字典,但是你的复制操作只适用于那个外部字典。内部字典没有被复制,实际上两者都是同一个字典。
如果您对字典使用深度复制而不是其复制方法,这将确保内部字典与 class 中的版本无关。
from copy import deepcopy
model = {**deepcopy(MainClass.InnerClass.default_model), 'user_id': 1}
否则,您可以将复制操作添加到您的 for 循环中。但是,这需要您考虑 default_model
中是否还有其他类型需要单独复制。例如,下面的代码不会对嵌套列表进行深度复制。如果可能的话,deepcopy 是处理这个问题的更好方法。
model = {"user_id": 1}
for k, v in cls.Meta.default_model.items():
if k not in model:
model[k] = v if not isinstance(v, dict) else v.copy()
我有简单的 class 和 default_model 像这样:
class User(BaseModel):
class Meta:
collection = db.client.users
default_model = {
'cooldowns': {
'bonus': 0,
'transfer': 0,
}
}
如何复制 Meta.default_model 而不将其链接到 class 本身?也就是说,命令是一次性的,而不是从 class 本身继承的。我已经尝试了两次尝试,但它们都与 class 相关联(
#第一次尝试
model = {"user_id": 1}
for k, v in cls.Meta.default_model.items():
if k not in model:
model[k] = v
#第二次尝试
model = {"user_id": 1} | cls.Meta.default_model.copy()
我的意思是:
class User:
class Meta:
default_model = {
"cooldowns": {
"bonous": 0
}
}
model = {}
for k, v in User.Meta.default_model.items():
model[k] = v
# It changes User.Meta.default_model
model['cooldowns']['bonous'] = 1
print(User.Meta.default_model)
我相信你要找的是deepcopy
from copy import deepcopy
class User:
class Meta:
default_model = {
"cooldowns": {
"bonus": 0,
"transfer": 0,
}
}
print(User.Meta.default_model)
new = deepcopy(User.Meta.default_model)
new["cooldowns"]["bonus"] = 5
print(new) # bonus now 5
print(User.Meta.default_model) # bonus still 0
这给出了输出:
{'cooldowns': {'bonus': 0, 'transfer': 0}}
{'cooldowns': {'bonus': 5, 'transfer': 0}}
{'cooldowns': {'bonus': 0, 'transfer': 0}}
您看到此行为(在 class 中更改的值也在新字典 model
中更改),因为您有一个嵌套字典。 cooldowns
的值本身就是一个字典,但是你的复制操作只适用于那个外部字典。内部字典没有被复制,实际上两者都是同一个字典。
如果您对字典使用深度复制而不是其复制方法,这将确保内部字典与 class 中的版本无关。
from copy import deepcopy
model = {**deepcopy(MainClass.InnerClass.default_model), 'user_id': 1}
否则,您可以将复制操作添加到您的 for 循环中。但是,这需要您考虑 default_model
中是否还有其他类型需要单独复制。例如,下面的代码不会对嵌套列表进行深度复制。如果可能的话,deepcopy 是处理这个问题的更好方法。
model = {"user_id": 1}
for k, v in cls.Meta.default_model.items():
if k not in model:
model[k] = v if not isinstance(v, dict) else v.copy()