云南网站建设,企业信息化软件定制开发

专业提供昆明网站建设, 昆明软件开发, 云南网站建设,企业信息化软件定制开发服务免费咨询QQ932256355

博客园 首页 新随笔 联系 订阅 管理

Python 特殊方法:属性访问与描述符的深度剖析

全面解读属性访问与描述符相关特殊方法__getattr____setattr____delattr____getattribute__ 以及描述符相关的 __get____set____delete____set_name____getstate____setstate__ 方法。通过示例展示如何利用这些方法实现属性的动态访问、赋值验证、删除控制以及对象的序列化和反序列化。

  • _getattr_****方法:当访问对象不存在的属性时被调用,可用于实现动态属性或提供默认值。例如,当访问一个不存在的属性时,返回一个固定的默认值:
class DynamicAttr:
    def __getattr__(self, name):
        if name == 'default_attr':
            return 'default value'
        raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
obj = DynamicAttr()
print(obj.default_attr)
  • _setattr_****方法:在设置对象属性时调用,可用于对属性赋值进行拦截和验证。例如,限制某个属性只能设置为特定类型的值:
class ValidatedAttr:
    def __setattr__(self, name, value):
        if name == 'age' and not isinstance(value, int):
            raise ValueError('Age must be an integer')
        super().__setattr__(name, value)
obj = ValidatedAttr()
obj.age = 25
  • _delattr_****方法:在删除对象属性时调用,可用于实现属性删除的自定义逻辑。例如,在删除属性时记录日志:
import logging
class LoggedAttr:
    def __delattr__(self, name):
        logging.info(f"Deleting attribute {name}")
        super().__delattr__(name)
obj = LoggedAttr()
obj.attr = 10
del obj.attr
  • _getattribute_****方法:在访问对象任何属性时都会调用,比 getattr 更优先,需谨慎使用以避免无限递归。例如:
class AllAttrAccess:
    def __getattribute__(self, name):
        print(f"Accessing attribute {name}")
        return super().__getattribute__(name)
obj = AllAttrAccess()
obj.some_attr = 10
print(obj.some_attr)
  • 描述符相关方法

  • _get_****方法:用于获取描述符管理的属性值。

  • _set_****方法:用于设置描述符管理的属性值。

  • _delete_****方法:用于删除描述符管理的属性时的逻辑处理。

  • _set_name_****方法:Python 3.6 及以上版本新增,描述符被赋值给类的属性时调用,可获取所属类和属性名。

  • 示例:通过描述符实现一个属性的验证和管理:

class ValidatedDescriptor:
    def __set_name__(self, owner, name):
        self.name = name
    def __get__(self, instance, owner):
        if instance is None:
            return self
        return instance.__dict__.get(self.name)
    def __set__(self, instance, value):
        if not isinstance(value, int):
            raise ValueError(f"{self.name} must be an integer")
        instance.__dict__[self.name] = value
class MyClass:
    validated_attr = ValidatedDescriptor()
obj = MyClass()
obj.validated_attr = 10
  • _getstate_setstate****方法:用于对象的序列化和反序列化,分别在对象被 pickle 时获取和恢复对象状态。例如,在序列化时,将某些敏感信息排除:
import pickle
class SensitiveData:
    def __init__(self):
        self.normal_data = 'normal'
        self.sensitive_data ='sensitive'
    def __getstate__(self):
        state = self.__dict__.copy()
        del state['sensitive_data']
        return state
    def __setstate__(self, state):
        self.__dict__.update(state)
obj = SensitiveData()
serialized = pickle.dumps(obj)
deserialized = pickle.loads(serialized)
print(deserialized.normal_data)
posted on 2025-03-03 15:10  TekinTian  阅读(58)  评论(0)    收藏  举报