__get__,__getattr__,__getattribute__的区别

class C(object):
  a = ‘abc‘
  def __getattribute__(self, *args, **kwargs):
    print("__getattribute__() is called")
    return object.__getattribute__(self, *args, **kwargs)
#    return "haha"
  def __getattr__(self, name):
    print("__getattr__() is called ")
    return name + " from getattr"

  def __get__(self, instance, owner):
    print("__get__() is called", instance, owner)
    return self

  def foo(self, x):
    print(x) 

class C2(object):
  d = C()
if __name__ == ‘__main__‘:
  c = C()
  c2 = C2()
  print(c.a)
  print(c.zzzzzzzz)
  c2.d
  print(c2.d.a) 

1.object.__getattr__(self, name)
当一般位置找不到attribute的时候,会调用getattr,返回一个值或AttributeError异常。

2.object.__getattribute__(self, name)
无条件被调用,通过实例访问属性。如果class中定义了__getattr__(),则__getattr__()不会被调用(除非显示调用或引发AttributeError异常)

3.object.__get__(self, instance, owner)
如果class定义了它,则这个class就可以称为descriptor。owner是所有者的类,instance是访问descriptor的实例,如果不是通过实例访问,而是通过类访问的话,instance则为None。(descriptor的实例自己访问自己是不会触发__get__,而会触发__call__,只有descriptor作为其它类的属性才有意义。)(所以下文的d是作为C2的一个属性被调用)

输出结果

__getattribute__() is called
abc
__getattribute__() is called
__getattr__() is called
zzzzzzzz from getattr
__get__() is called <__main__.C2 object at 0x16d2310> <class ‘__main__.C2‘>
__get__() is called <__main__.C2 object at 0x16d2310> <class ‘__main__.C2‘>
__getattribute__() is called
abc 

小结

可以看出,每次通过实例访问属性,都会经过__getattribute__函数。而当属性不存在时,仍然需要访问__getattribute__,不过接着要访问__getattr__。这就好像是一个异常处理函数。
每次访问descriptor(即实现了__get__的类),都会先经过__get__函数。

需要注意的是,当使用类访问不存在的变量是,不会经过__getattr__函数。而descriptor不存在此问题,只是把instance标识为none而已。

原文地址:https://www.cnblogs.com/chenyoude/p/9876945.html

时间: 2024-10-13 08:08:08

__get__,__getattr__,__getattribute__的区别的相关文章

python3中__get__,__getattr__,__getattribute__的区别

__get__,__getattr__和__getattribute都是访问属性的方法,但不太相同. object.__getattr__(self, name) 当一般位置找不到attribute的时候,会调用getattr,返回一个值或AttributeError异常. object.__getattribute__(self, name) 无条件被调用,通过实例访问属性.如果class中定义了__getattr__(),则__getattr__()不会被调用(除非显示调用或引发Attrib

python中__get__,__getattr__,__getattribute__的区别

__get__,__getattr__和__getattribute都是访问属性的方法,但不太相同. object.__getattr__(self, name) 当一般位置找不到attribute的时候,会调用getattr,返回一个值或AttributeError异常. object.__getattribute__(self, name) 无条件被调用,通过实例访问属性.如果class中定义了__getattr__(),则__getattr__()不会被调用(除非显示调用或引发Attrib

转载Python中__getattr__ __getattribute__ __get__解释

来源:http://www.myexception.cn/perl-python/620096.html python中__get__,__getattr__,__getattribute__的区别 __get__,__getattr__和__getattribute都是访问属性的方法,但不太相同. object.__getattr__(self, name) 当一般位置找不到attribute的时候,会调用getattr,返回一个值或AttributeError异常. object.__get

python中getattr(),__getattr__(),__getattribute__()探究

getattr() 为 函数,而__getattr__(), __getattribute__()为类的方法 1. getattr() 参数为 (object,attr_name,default value) 会调用该object的__getattribute__()方法,如果没有返回值,继续调用__getattr__()方法 2. 任何调用实例的属性值,都会调用到__getattribute__方法,如果没有返回值会继续调用__getattr__(),也就是__getattr__() 相当于e

__getattr__,__getattribute__和__get__的区别

dir(object)  列出对象的大多数属性 getattr(object, name) 从object对象中获取name字符串指定的属性 hasattr(object, name) 如果object对象中存在指定的属性, 或者能以某种方式通过object 对象获取指定的属性, 返回True setattr(object, name, value) 把object对象指定属性的值设为value, 可能会创建一个新属性, 或者覆盖现有的属性 getattr(obj, 'attr') 以及obj.

Python-魔法函数__getattr__()与__getattribute__()的区别

如果某个类定义了 __getattribute__() 方法,在 每次引用属性或方法名称时 Python 都调用它(特殊方法名称除外,因为那样将会导致讨厌的无限循环). 如果某个类定义了 __getattr__() 方法,Python 将只有在查找不到属性时才会调用它.如果实例 x 定义了属性 color, x.color 将 不会 调用x.__getattr__('color'):而只会返回 x.color 已定义好的值 1 class User: 2 def __init__(self, n

__getattr__ 与 __getattribute__的区别

原文博客地址 http://www.cnblogs.com/bettermanlu/archive/2011/06/22/2087642.html 原文地址:https://www.cnblogs.com/654321cc/p/8529009.html

Python-类属性查询协议-__getattr__ __getattribute__

__getattr__ 查找不到类属性的时候调用 class BeiMenChuiXue: def __init__(self, name): self.name = name def __getattr__(self, item): print("%s not find", item) raise Exception("实例方法没有找到") if __name__ == '__main__': bei_men_chui_xue = BeiMenChuiXue(&q

python 中的特殊方法,纠正自己笨笨的记忆

1. __new__ 和 __init__ 的区别 python 2.x 老式类(默认继承type) class A: pass 老式类中没有__new__类方法(也就是说定义也不会执行,它不是老式类的类方法),__Init__ 作为构造函数,创建实例对象,并初始化. 过程: 类 => __init__() => 实例(self)创建并初始化 __init__: 不能有返回值 python 3 和 python 2.x(显示继承新式类) class A(object): pass 注: 在Py