python中的__getattr____getattribute____setattr____delattr____dir__

Posted 丁壮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python中的__getattr____getattribute____setattr____delattr____dir__相关的知识,希望对你有一定的参考价值。

__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]

 

























以上是关于python中的__getattr____getattribute____setattr____delattr____dir__的主要内容,如果未能解决你的问题,请参考以下文章

python中的__getattr____getattribute____setattr____delattr____dir__

python 类中__getattr__的使用

python之 __getattr____getattr____getitem____setitem__ 使用

python __getattr__

Python的__getattr__和__getattribute__

python中__getattr__和__getattribute__区别