代码
这里要创建一个描述符,根据要求(如隐藏敏感信息、正确地设置日期的格式)对属性的值进行变换,并返回修改后的版本:
from dataclasses import dataclass
from datetime import datetime
from functools import partial
from typing import Callable
class BaseFieldTransformation:
def __init__(self, transformation: Callable[[], str]) -> None:
print("初始化")
self._name = None
self.transformation = transformation
def __get__(self, instance, owner):
print("get执行")
if instance is None:
return self
raw_value = instance.__dict__[self._name]
return self.transformation(raw_value)
def __set_name__(self, owner, name):
print("set_name执行")
self._name = name
def __set__(self, instance, value):
print("set执行")
instance.__dict__[self._name] = value
ShowOriginal = partial(BaseFieldTransformation, transformation=lambda x: x)
HideField = partial(
BaseFieldTransformation, transformation=lambda x: "**redacted**"
)
FormatTime = partial(
BaseFieldTransformation,
transformation=lambda ft: ft.strftime("%Y-%m-%d %H:%M"),
)
@dataclass
class LoginEvent:
username: str = ShowOriginal()
password: str = HideField()
ip: str = ShowOriginal()
timestamp: datetime = FormatTime()
def serialize(self) -> dict:
return {
"username": self.username,
"password": self.password,
"ip": self.ip,
"timestamp": self.timestamp,
}
if __name__ == '__main__':
le = LoginEvent("john", "secret password", "1.1.1.1", datetime.utcnow())
>>> le = LoginEvent("john", "secret password", "1.1.1.1", datetime.
utcnow())
>>> vars(le)
{'username': 'john', 'password': 'secret password', 'ip': '1.1.1.1',
'timestamp': ...}
>>> le.serialize()
{'username': 'john', 'password': '**redacted**', 'ip': '1.1.1.1',
'timestamp': '...'}
>>> le.password
'**redacted**'
这段代码使用了 Python 中的描述符(Descriptor)和数据类(Data Class)来实现一个 LoginEvent 类,该类用于表示用户的登录事件,并包含了一些敏感信息。其中,BaseFieldTransformation 类是一个基类,它定义了描述符的通用行为。LoginEvent 类继承了 dataclass 装饰器,这使得该类具有自动生成 init__、__repr 等方法的特性。
BaseFieldTransformation 描述符有三个方法:
__init__: 在对象创建时被调用,用于初始化对象状态;
__get__: 在属性被访问时被调用,用于获取属性的值;
__set__: 在属性被赋值时被调用,用于设置属性的值;
__set_name__: 在类中定义属性时被调用,用于设置描述符名称。
在该代码中,我们定义了三个具体的 BaseFieldTransformation 子类:ShowOriginal、HideField 和 FormatTime。这些子类通过 partial 函数将 transformation 参数预设为不同的函数,以便对应不同的字段转换方式。例如,ShowOriginal 字段保持原样,而 HideField 字段使用 "redacted" 来代替其真实值。
最后,我们使用 LoginEvent 类创建了一个数据记录。该数据记录用于存储用户的登录事件,包括用户名、密码、IP 地址和时间戳。其中,用户名和 IP 地址字段使用 ShowOriginal 描述符,这意味着它们不会被转换。密码字段使用 HideField 描述符,这意味着它将被替换为 "redacted"。时间戳字段使用 FormatTime 描述符,这意味着它将按照指定格式进行格式化。登录事件还包括一个 serialize 方法,用于将该事件序列化为 dict 格式的数据。
标签:__,name,示例,self,描述符,详解,password,transformation
From: https://www.cnblogs.com/weiweivip666/p/17299269.html