add pytest

This commit is contained in:
bridge
2025-12-14 15:13:48 +08:00
parent 6b0bf25699
commit 30a10bbb1c
4 changed files with 174 additions and 64 deletions

View File

@@ -304,8 +304,10 @@ class Avatar(
self._init_known_regions()
def __hash__(self) -> int:
if not hasattr(self, 'id'):
# 防御性编程如果id尚未初始化例如deepcopy过程中使用对象内存地址
return super().__hash__()
return hash(self.id)
def __str__(self) -> str:
return str(self.get_info(detailed=False))

View File

@@ -6,10 +6,11 @@ Avatar读档反序列化Mixin
读档策略:
- 两阶段加载先加载所有Avatarrelations留空再重建relations网络
- 引用对象通过id从全局字典获取如techniques_by_id
- weapon/auxiliary拷贝后恢复special_data
- weapon/auxiliary拷贝后恢复special_data避免deepcopy带来的递归/崩溃风险)
- 错误容错:缺失的引用对象会跳过而不是崩溃
"""
from typing import TYPE_CHECKING
import copy
if TYPE_CHECKING:
from src.classes.world import World
@@ -98,21 +99,26 @@ class AvatarLoadMixin:
if item_id in items_by_id:
avatar.items[items_by_id[item_id]] = quantity
# 重建weapon深拷贝因为special_data是实例特有的
# 重建weapon
# 使用copy而非deepcopy避免潜在的递归引用导致的崩溃且性能更好
# special_data 是实例特有的,需要单独赋值
weapon_id = data.get("weapon_id")
if weapon_id is not None and weapon_id in weapons_by_id:
import copy
avatar.weapon = copy.deepcopy(weapons_by_id[weapon_id])
# 浅拷贝:复制引用,但 weapon.special_data 会被共享
# 所以需要手动重新赋值 special_data
weapon_proto = weapons_by_id[weapon_id]
avatar.weapon = copy.copy(weapon_proto)
avatar.weapon.special_data = data.get("weapon_special_data", {})
# 恢复兵器熟练度
avatar.weapon_proficiency = float(data.get("weapon_proficiency", 0.0))
# 重建auxiliary深拷贝因为special_data是实例特有的
# 重建auxiliary
# 同上使用copy
auxiliary_id = data.get("auxiliary_id")
if auxiliary_id is not None and auxiliary_id in auxiliaries_by_id:
import copy
avatar.auxiliary = copy.deepcopy(auxiliaries_by_id[auxiliary_id])
auxiliary_proto = auxiliaries_by_id[auxiliary_id]
avatar.auxiliary = copy.copy(auxiliary_proto)
avatar.auxiliary.special_data = data.get("auxiliary_special_data", {})
# 重建spirit_animal
@@ -197,4 +203,3 @@ class AvatarLoadMixin:
avatar.recalc_effects()
return avatar