1️⃣ 设计目标:一句话说清楚 🤏
“让我像搭积木一样,把任意结构(dict / dataclass / JSON Schema)瞬间变成不可变对象,还带代码提示!”
2️⃣ 懒人工厂代码(Python 3.10+)
from typing import Any, get_type_hints
import copy
import json
class特制构造器:
"""
链式 · 类型安全 · 可冻结 · 可序列化
"""
__slots__ = ("_data", "_frozen")
def __init__(self, **kwargs):
# 1. 注入默认骨架
self._data = self._defaults() | kwargs
# 2. 类型检查
self._validate()
self._frozen = False
@classmethod
def _defaults(cls) -> dict[str, Any]:
"""子类重写 = 声明默认字段"""
return {}
def _validate(self):
"""运行时类型检查"""
hints = get_type_hints(self)
for k, v in self._data.items():
if (h := hints.get(k)) and not isinstance(v, h):
raise TypeError(f"{k} 需要 {h},但给了 {type(v)}")
# ——— 链式装配 ———
def with_(self, **kwargs):
"""链式更新,返回新实例"""
new = copy.deepcopy(self)
new._data |= kwargs
new._validate()
return new
# ——— 冻结 · 不可变 ———
def freeze(self):
"""冻住,不许改"""
self._frozen = True
return self
def __setattr__(self, key, value):
if getattr(self, "_frozen", False):
raise RuntimeError("实例已冻结 ❄️")
super().__setattr__(key, value)
# ——— 魔法方法 ———
def __getattr__(self, item):
try:
return self._data[item]
except KeyError:
raise AttributeError(item) from None
def __repr__(self):
return f"{self.__class__.__name__}({self._data})"
# ——— 序列化 ———
def to_dict(self):
return copy.deepcopy(self._data)
def to_json(self, *, indent=2):
return json.dumps(self._data, indent=indent, ensure_ascii=False)
# ——— 使用示例:定义你的“特制结构” ———
class 电竞主机(特制构造器):
"""来一台 2025 年最香配置"""
@classmethod
def _defaults(cls):
return {
"cpu": "R9-7950X3D",
"gpu": "RTX4090D",
"ram": 32,
"ssd": 2000,
"rgb": True,
}
# ——— 实战:链式 + 冻结 + JSON ———
if __name__ == "__main__":
pc = 电竞主机() \
.with_(gpu="RTX5080", ram=64) \
.freeze()
print(pc) # 电竞主机({'cpu': 'R9-7950X3D', ...})
print(pc.gpu) # RTX5080
print(pc.to_json()) # 直接导出 JSON 给前端
# pc.rgb = False # RuntimeError: 实例已冻结 ❄️
3️⃣ 运行结果图位(文字版)
电竞主机({'cpu': 'R9-7950X3D', 'gpu': 'RTX5080', 'ram': 64, 'ssd': 2000, 'rgb': True})
RTX5080
{
"cpu": "R9-7950X3D",
"gpu": "RTX5080",
"ram": 64,
"ssd": 2000,
"rgb": true
}
4️⃣ 特色拆解(表情包对照)
| 能力 | 实现技巧 | 表情包 |
|---|---|---|
| 默认骨架 | _defaults() 类方法 | “懒人骨架”🦴 |
| 类型检查 | get_type_hints+isinstance | “安检门”🛂 |
| 链式更新 | with_(...) 返回深拷贝 | “乐高拼接”🧩 |
| 不可变 | __setattr__ 里抛异常 | “冰封王座”❄️ |
| 序列化 | json.dumps 深拷贝 | “一键发朋友圈”📸 |
5️⃣ 想再卷一点?给你 3 个进阶按钮 🚀
- 缓存哈希 → 重写
__hash__,让实例进set/dict - 可选 Pydantic → 把
_validate换成BaseModel.parse_obj - 自动生成 → 读 JSON Schema 动态创建子类,“schema → 类” 秒变 TypeScript 体验
🎯 总结口诀(背它!)
“默认骨架 + 类型安检 + 链式 with + 冻结锁 + JSON 秒出”
从此构造对象不用写七行__init__,一口价,全带走🛒