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__方法,获取默认值;否则会直接抛错。

  • 相关阅读:
    Java 字典
    java 集合
    Java Array类、大数据运算、包装类
    java String、StringBuilder 、正则表达式
    Java时间日期类 Date、DateFormat、Calendar类
    java包的声明、导入、System类
    java正则表达式
    java-StringBuffer类和StringBuilder类
    java-String类
    java的API,Object类,equals方法,toString方法
  • 原文地址:https://www.cnblogs.com/Deaseyy/p/13676317.html
Copyright © 2011-2022 走看看