zoukankan      html  css  js  c++  java
  • __getattr__ 和 __getattribute__ 区别

    这两个是类对象的魔法函数,在访问对象属性的时候会被调用

     1 class A(object):
     2   def __init__(self, x):
     3     self.x = x
     4 
     5   def __getattr__(self, item):
     6     print('run __getattr__')
     7     return 100
     8 
     9   def __getattribute__(self, item):
    10     print('run __getattribute__')
    11     return super(A, self).__getattribute__(item)
    12 
    13 a = A(10)
    14 print(a.x)
    15 print(a.y)

    结果:
    # a.x
    >> 执行 __getattribute__ >> 10 # a.y
    >> 执行 __getattribute__ >> 执行 __getattr__ >> 100

    从结果可以看出,获取对象属性时:

      无论属性是否存在,都会先调用__getattribute__ 方法;

      在调用__getattribute__ 方法获取不到属性时,才会去调用__getattr__方法;

      所以我们可在__getattr__方法中返回属性不存在时的默认值。

    拿drf源码中的一个实际例子来说:

    class Request(object):
      @property
      def content_type(self):
        meta = self._request.META
        return meta.get(CONTENT_TYPE', meta.get('HTTP_CONTENT_TYPE', ''))
      
      @property   def query_params(self):   return self._request.GET      def __getattr__(self, attr): try: return getattr(self._request, attr) except AttributeError: return self.__getattribute__(attr)

    DRF中的request 对django原生的request对象做了二次封装,Request类中也实现了一些方法用于获取原生request中的一些属性,但是实现的方法有限,这些方法并不能取到原生request的所有属性;所以使用__getattr__来操作,在当前request对象取不到指定属性时,就会执行__getattr__方法,去_request(原生request)中取该属性。

    使用getattr获取属性:

    使用getattr()方法获取对象属性时,也是同样的调用关系,只不过只有在getattr()带第三个参数作为默认值时,才会调用__getattr__方法,获取默认值;否则会直接抛错。

  • 相关阅读:
    【小程序】订阅消息
    【小程序】轮播图
    【小程序】全局变量的设置、使用、修改、全局方法执行
    【RN】标题栏右边添加自定义按钮或加事件
    【RN】阴影react-native-shadow
    【vue】点击复制到剪贴板的方法( clipboard )
    Q-learning和Sarsa的区别
    Q-learning之一维世界的简单寻宝
    使用tensorflow时,关于GPU的设置
    安装Matlab出现弹出DVD1插入DVD2的提示怎么办?
  • 原文地址:https://www.cnblogs.com/Deaseyy/p/13676317.html
Copyright © 2011-2022 走看看