如何在嵌套Python dataclass的字典字段中隐藏敏感数据?
解决Python Dataclass敏感字段在repr中替换的问题
要实现只隐藏Grade类中score字典里的指定敏感字段(Password和Chemistry),而不是隐藏整个字段,核心思路是重写Grade类的__repr__方法,在方法中对敏感字段进行替换后再生成字符串表示。
完整实现代码
from dataclasses import dataclass, field import copy @dataclass class Grade: school: str = "school_default" classroom: str = "classroom_default" # 修正default_factory写法:必须传入可调用对象(lambda返回字典) score: dict = field(default_factory=lambda: { 'total': {'Math':100, 'English':90, 'Chemistry':95, 'Password':11111} }) def __repr__(self): # 深拷贝score字典,避免修改原实例的原始数据 safe_score = copy.deepcopy(self.score) # 替换指定敏感字段 if 'total' in safe_score: sensitive_fields = ['Chemistry', 'Password'] for field_name in sensitive_fields: if field_name in safe_score['total']: safe_score['total'][field_name] = '******' # 构造符合dataclass风格的repr字符串 return ( f"Grade(school='{self.school}', classroom='{self.classroom}', " f"score={safe_score})" ) @dataclass class Student: name: str = "Alice" age: int = field(default=10, repr=False) sex: str = 'female' grade: Grade = None # 初始化实例 s1 = Student( 'Jimmy', 20, 'Male', Grade('school2', 'classroom2', { 'total': {'Math':99, 'English':88, 'Chemistry':77, 'Password':33333} }) ) print(s1)
关键说明
- 修正
default_factory错误:原代码中score字段的default_factory直接传入字典会报错,因为default_factory要求是无参可调用对象,这里改用lambda返回默认字典。 - 重写
Grade.__repr__:- 通过
copy.deepcopy复制score字典,避免修改实例的原始数据; - 遍历指定的敏感字段列表,将对应值替换为
******; - 手动构造符合dataclass默认风格的字符串,保证输出格式一致。
- 通过
- Student类无需额外修改:因为Student的repr会自动调用嵌套的Grade实例的
__repr__方法,最终会输出处理后的敏感字段。
运行代码后,输出结果与目标完全一致:
Student(name='Jimmy', sex='Male', grade=Grade(school='school2', classroom='classroom2', score={'total': {'Math': 99, 'English': 88, 'Chemistry': '******', 'Password': '******'}}))
内容的提问来源于stack exchange,提问作者fzhurd
相关产品推荐
相关产品推荐

