• Python学习笔记--属性的访问控制


    三、属性的访问控制

    之前也有讲到过,Python 没有真正意义上的私有属性。然后这就导致了对 Python 类的封装性比较差。我们有时候会希望 Python 能够定义私有属性,然后提供公共可访问的 get 方法和 set 方法。Python 其实可以通过魔术方法来实现封装。

    方法说明
    __getattr__(self, name)该方法定义了你试图访问一个不存在的属性时的行为。因此,重载该方法可以实现捕获错误拼写然后进行重定向, 或者对一些废弃的属性进行警告。
    __setattr__(self, name, value)定义了对属性进行赋值和修改操作时的行为。不管对象的某个属性是否存在,都允许为该属性进行赋值.有一点需要注意,实现 __setattr__ 时要避免"无限递归"的错误,
    __delattr__(self, name)__delattr____setattr__ 很像,只是它定义的是你删除属性时的行为。实现 __delattr__ 是同时要避免"无限递归"的错误
    __getattribute__(self, name)__getattribute__ 定义了你的属性被访问时的行为,相比较,__getattr__ 只有该属性不存在时才会起作用。因此,在支持 __getattribute__ 的 Python 版本,调用__getattr__ 前必定会调用 __getattribute__``__getattribute__ 同样要避免"无限递归"的错误。

    通过上面的方法表可以知道,在进行属性访问控制定义的时候你可能会很容易的引起一个错误,可以看看下面的示例:

    def __setattr__(self, name, value):
        self.name = value
        # 每当属性被赋值的时候, ``__setattr__()`` 会被调用,这样就造成了递归调用。
        # 这意味这会调用 ``self.__setattr__('name', value)`` ,每次方法会调用自己。这样会造成程序崩溃。
    
    def __setattr__(self, name, value):
        # 给类中的属性名分配值
        self.__dict__[name] = value  
        # 定制特有属性
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    上面方法的调用具体示例如下:

    #!/usr/bin/env python3
    # -*- coding: UTF-8 -*-
    
    class User(object):
        def __getattr__(self, name):
            print('调用了 __getattr__ 方法')
            return super(User, self).__getattr__(name)
    
        def __setattr__(self, name, value):
            print('调用了 __setattr__ 方法')
            return super(User, self).__setattr__(name, value)
    
        def __delattr__(self, name):
            print('调用了 __delattr__ 方法')
            return super(User, self).__delattr__(name)
    
        def __getattribute__(self, name):
            print('调用了 __getattribute__ 方法')
            return super(User, self).__getattribute__(name)
    
    
    if __name__ == '__main__':
        user = User()
        # 设置属性值,会调用 __setattr__
        user.attr1 = True
        # 属性存在,只有__getattribute__调用
        user.attr1
        try:
            # 属性不存在, 先调用__getattribute__, 后调用__getattr__
            user.attr2
        except AttributeError:
            pass
        # __delattr__调用
        del user.attr1
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    输出的结果:

    调用了 __setattr__ 方法
    调用了 __getattribute__ 方法
    调用了 __getattribute__ 方法
    调用了 __getattr__ 方法
    调用了 __delattr__ 方法
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    HTML做一个个人博客页面(纯html代码)
    给程序员准备的“蜜糍”--SOD框架简介
    【来点小剧场--项目测试报告】个人博客项目自动化测试
    汽车射频之基础
    关于远程工作的面试可能存在的陷阱
    倾斜光栅的参数优化与容差分析
    数据库缓存服务——NoSQL之Redis配置与优化
    stm32Cubemx USB虚拟串口
    基于SpringBoot+MyBatis-Plus的图书管理系统
    数据结构历年考研真题对应知识点(栈)
  • 原文地址:https://blog.csdn.net/liufang_imei/article/details/134249802