欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python中的__getattr__、__getattribute__、__setattr__、__delattr__、__dir__

程序员文章站 2023-12-01 22:03:04
__getattr__: 属性查找失败后,解释器会调用 __getattr__ 方法. a.tmpnone 表达式执行顺序: 1、首先会检查a实例有没有名为x的属性 2、到类(a.__class__)中查找 3、顺着继承树继续查找. 4、调用a所属类中定义的 __getattr__ 方法,传入sel ......

__getattr__:
     属性查找失败后,解释器会调用 __getattr__ 方法.

class tmptest:
    def __init__(self):
        self.tmp = 'tmp123'
    def __getattr__(self, item):
        raise attributeerror('{} object has no attribute {}'.format(type(self), item))
a=tmptest()

print(a.tmp)
结果:
    tmp123

print(a.tmpnone)
结果:
    traceback (most recent call last):
      file "d:/pythonscript/leetcode/leetcode.py", line 12, in <module>
        print(a.tmpnone)
      file "d:/pythonscript/leetcode/leetcode.py", line 7, in __getattr__
        raise attributeerror(msg.format(tmp_cls, item))
    attributeerror: <class '__main__.tmptest'> object has no attribute tmpnone

 a.tmpnone 表达式执行顺序:
       1、首先会检查a实例有没有名为x的属性
       2、到类(a.__class__)中查找
       3、顺着继承树继续查找.
       4、调用a所属类中定义的 __getattr__ 方法,传入self和属性名称的字符串形式(如 'tmpnone').


__getattribute__:
 1、尝试获取指定的属性时总会调用这个方法,寻找的属性是特殊属性或特殊方法时除外.
    2、点号与 getattr 和 hasattr 内置函数会触发这个方法.
    3、调用 __getattribute__ 方法且抛出 attributeerror 异常时,才会调用 __getattr__ 方法.
    4、为了在获取实例的属性时不导致无限递归,__getattribute__ 方法的实现要使用 super().__getattribute__(name)

class tmptest:

    def __getattr__(self, item):
        print("getting __getattr__ {}".format(item))
        self.__dict__[item] = '__getattr__'
        return '__getattr__'

    def __getattribute__(self, item):
        print ("getting __getattribute__ {}".format(item))
        if item=='x':
            raise attributeerror
        return object.__getattribute__(self, item)

    def __setattr__(self, key, value):
        print("getting __setattr__ {}".format(key))
        return object.__setattr__(self, key, value)

a=tmptest()
a.x='getattr'
print (a.x)

结果:
getting __setattr__ x   
getting __getattribute__ x       #抛出异常
getting __getattr__ x            #执行__getattr__
getting __getattribute__ __dict__  
__getattr__


__setattr__:
    尝试设置指定的属性时会调用这个方法.点号和 setattr 内置函数会触发这个方法.例如我们上面的例子a.x='getattr'和 setattr(a, 'x', "getattr") 都会触发 tmptest.__setattr__(a, 'x', "getattr") 方法.,
    如果实现了 __getattr__ 方法,最好同时定义 __setattr__ 方法

__delattr__:
    只要使用del语句删除属性,就会调用这个方法.例如,del a.x 语句触发 class.__delattr__(a, 'x') 方法
    实现方法:

    def __delattr__(self, item):
        print ("getting __delattr__ {}".format(item))
        del self.__dict__[item]


dir():
    1、在没有参数的情况下,返回当前作用域内的名称列表。
    2、如果对象有一个名为dir()的方法,那么这个方法就会被调用
    3、模块对象,返回模块的属性列表
    4、类对象,返回累的属性名称和基类的属性列表

看下官方的文档例子:

    >>> import struct
    >>> dir()   # show the names in the module namespace  
    ['__builtins__', '__name__', 'struct']
    
    >>> dir(struct)   # show the names in the struct module
    ['struct', '__all__', '__builtins__', '__cached__', '__doc__', '__file__',
     '__initializing__', '__loader__', '__name__', '__package__',
     '_clearcache', 'calcsize', 'error', 'pack', 'pack_into',
     'unpack', 'unpack_from']
     
    >>> class shape:
    ...     def __dir__(self):
    ...         return ['area', 'perimeter', 'location']
    >>> s = shape()
    >>> dir(s)
    ['area', 'location', 'perimeter']