这里的属性即包括属性变量,也包括属性方法。即类的变量和方法。
  当访问某个实例属性时, getattribute会被无条件调用,如未实现自己的getattr方法,会抛出AttributeError提示找不到这个属性,如果自定义了自己getattr方法的话,方法会在这种找不到属性的情况下被调用,比如上面的例子中的情况。所以在找不到属性的情况下通过实现自定义的getattr方法来实现一些功能是一个不错的方式,因为它不会像getattribute方法每次都会调用可能会影响一些正常情况下的属性访问
 
  使用这几个方法可以实现拦截器啥、动态代理、统一log等功能。
 
  举例:
  1、使用__getattribute__实现统一的打印日志功能。使用__getattribute__方法拦截了属性和方法的访问。__getattribute__只有在新式类中才能使用。
  

  1. # -*- coding: utf- -*-
  2. class Fjs(object):
  3. def __init__(self, name):
  4. self.name = name
  5.  
  6. def hello(self):
  7. print "said by : ", self.name
  8.  
  9. def __getattribute__(self, item):
  10. print "访问了特性:" + item
  11. return object.__getattribute__(self, item)
  12.  
  13. fjs = Fjs("fjs")
  14. print fjs.name
  15. fjs.hello()

输出:

  1. 访问了特性:name
  2. fjs
  3. 访问了特性:hello
  4. said by : 访问了特性:name
  5. fjs

  2、这里通过__getattr__方法,将所有的特性的访问都路由给了内部的fjs对象

  1. # -*- coding: utf- -*-
  2. class Fjs(object):
  3. def __init__(self, name):
  4. self.name = name
  5.  
  6. def hello(self):
  7. print "said by : ", self.name
  8.  
  9. def fjs(self, name):
  10. if name == self.name:
  11. print "yes"
  12. else:
  13. print "no"
  14.  
  15. class Wrap_Fjs(object):
  16. def __init__(self, fjs):
  17. self._fjs = fjs
  18.  
  19. def __getattr__(self, item):
  20. if item == "hello":
  21. print "调用hello方法了"
  22. elif item == "fjs":
  23. print "调用fjs方法了"
  24. return getattr(self._fjs, item)
  25.  
  26. fjs = Wrap_Fjs(Fjs("fjs"))
  27. fjs.hello()
  28. fjs.fjs("fjs")

输出:

  1. 调用hello方法了
  2. said by : fjs
  3. 调用fjs方法了
  4. yes

  3、使用类的继承实现。则不会路由,子类直接继承了父类的属性和方法

  1. # -*- coding: utf- -*-
  2. class Fjs(object):
  3. def __init__(self, name):
  4. self.name = name
  5.  
  6. def hello(self):
  7. print "said by : ", self.name
  8.  
  9. def fjs(self, name):
  10. if name == self.name:
  11. print "yes"
  12. else:
  13. print "no"
  14.  
  15. class Wrap_Fjs(Fjs):
  16. def __init__(self, fjs):
  17. self._fjs = fjs
  18.  
  19. def __getattr__(self, item):
  20. if item == "hello":
  21. print "调用hello方法了"
  22. elif item == "fjs":
  23. print "调用fjs方法了"
  24. return getattr(self._fjs, item)
  25.  
  26. fjs = Wrap_Fjs(Fjs("fjs"))
  27. fjs.hello()
  28. fjs.fjs("fjs")

输出:

  1. said by : fjs
  2. yes

  4、猜一下结果,理解其妙用

  1. # 例子在原来的基础上简化了一下,排除依赖和干扰,详细参见原项目
  2. class UrlGenerator(object):
  3. def __init__(self, root_url):
  4. self.url = root_url
  5.  
  6. def __getattr__(self, item):
  7. if item == 'get' or item == 'post':
  8. print self.url
  9. return UrlGenerator('{}/{}'.format(self.url, item))
  10.  
  11. url_gen = UrlGenerator('http://xxxx')
  12. url_gen.users.show.get

  5、通过转换,可以像访问属性一样访问dict中的键值对

  1. class ObjectDict(dict):
  2. def __init__(self, *args, **kwargs):
  3. super(ObjectDict, self).__init__(*args, **kwargs)
  4.  
  5. def __getattr__(self, name):
  6. value = self[name]
  7. if isinstance(value, dict):
  8. value = ObjectDict(value)
  9. return value
  10.  
  11. if __name__ == '__main__':
  12. od = ObjectDict(asf={'a': }, d=True)
  13. print od.asf, od.asf.a # {'a': }
  14. print od.d # True
 
参考:
1、https://www.jianshu.com/p/885d59db57fc
2、https://www.cnblogs.com/xybaby/p/6280313.html

Python的__getattribute__ vs __getattr__的妙用的更多相关文章

  1. python魔法函数__dict__和__getattr__的妙用

    python魔法函数__dict__和__getattr__的妙用 __dict__ __dict__是用来存储对象属性的一个字典,其键为属性名,值为属性的值. 既然__dict__是个字典那么我们就 ...

  2. python魔法方法:__getattr__,__setattr__,__getattribute__

    python魔法方法:__getattr__,__setattr__,__getattribute__ 难得有时间看看书....静下心来好好的看了看Python..其实他真的没有自己最开始想的那么简单 ...

  3. python基础---- __getattribute__----__str__,__repr__,__format__----__doc__----__module__和__class__

    目录: 一. __getattribute__ 二.__str__,__repr__,__format__ 三.__doc__ 四.__module__和__class__ 一. __getattri ...

  4. python魔法函数之__getattr__与__getattribute__

    getattr 在访问对象的属性不存在时,调用__getattr__,如果没有定义该魔法函数会报错 class Test: def __init__(self, name, age): self.na ...

  5. python __getattribute__、__getattr__、__setattr__详解

    __getattribute__ 官方文档中描述如下: 该方法可以拦截对对象属性的所有访问企图,当属性被访问时,自动调用该方法(只适用于新式类).因此常用于实现一些访问某属性时执行一段代码的特性. 需 ...

  6. Python __getattribute__ vs __getattr__

    # 例子在原来的基础上简化了一下,排除依赖和干扰,详细参见原项目 class UrlGenerator(object): def __init__(self, root_url): self.url ...

  7. __getattribute__()、__getattr__()、__setattr__()、__delattr__()

    访问顺序: 实例的__getattribute__().Descriptor的__get__().实例的__dict__.只读Descriptor的__get__().实例的__getattr__() ...

  8. python中的__dict__,__getattr__,__setattr__

    python class 通过内置成员dict 存储成员信息(字典) 首先用一个简单的例子看一下dict 的用法 class A(): def __init__(self,a,b): self.a = ...

  9. Python的__getattribute__二三事

    本来以为自己对__getattribute__已经比较了解了,结果用到的时候,才发现有一些知识点之前一直没有真正弄明白,记录如下(针对python3,python2差异较大): object类有__g ...

随机推荐

  1. c#后台线程更新界面

    参考文章<C# 线程更新UI界面> 主窗口 public frmMain() { InitializeComponent(); } /// <summary> /// 主窗口加 ...

  2. MySQL几个特别语法示例

    简单介绍MySQL中几种特殊语法的用法: 1.创建示例用表和数据: 创建employees表[注:与SQL Server示例数据库Northwind中的表employees相同的表结构]: CREAT ...

  3. java 数组冒泡排序、转置(降序)

    1.java 数组冒泡排序 排序的基本原理(升序): 原始数据:  2 .1 .9 .0 .5 .3 .7 .6 .8: 第一次排序: 1  .2 .0 .5 .3 .7 .6 .8 .9 : 第二次 ...

  4. Python类总结-析构函数和__call__方法

    class Foo: def __init__(self): pass #析构函数 def __del__(self): print('解释器要销毁我了,我要做最后一次呐喊') def __call_ ...

  5. Django+Nginx+uwsgi搭建自己的博客(七)

    上一篇博客中介绍了Blogs App的部分后端功能的实现,在这篇博客中,将继续为大家介绍Blogs App中前端功能的实现. 首先来看发布博客功能的前端页面.在blogs/templates/blog ...

  6. 洛谷——P1821 [USACO07FEB]银牛派对Silver Cow Party

    P1821 [USACO07FEB]银牛派对Silver Cow Party 题目描述 One cow from each of N farms (1 ≤ N ≤ 1000) conveniently ...

  7. hpu 1194 Sequence

    HS(Handsome)的Ocean在纸上写下NN个整数,Ocean把它定义为OO序列. Ocean认为一个序列的价值的是:序列中不同元素个数. 现在他想知道OO序列中所有子序列的价值之和. 比如说: ...

  8. PHP的数据类型与常量使用

    数据类型之间的相互转换 1.强制转换:setType(变量,类型):这个函数将原变量的类型改变//integer,int,float,double,bool,boolen,string,arry,ob ...

  9. 2017-2018-1 JAVA实验站 冲刺 day01

    2017-2018-1 JAVA实验站 冲刺 day01 各个成员在 Alpha 阶段认领的任务 小组成员 分工 任务量 张韵琪 写博客.后期市场推广,营销.打杂.各职能的配合 齐力锋 提供宣传用图. ...

  10. 1.6(SQL学习笔记)存储过程

    一.什么事存储过程 可以将存储过程看做是一组完成某个特定功能的SQL语句的集合. 例如有一个转账功能(A向B转账50),先将账户A中金额扣除50,然后将账户B中金额添加50. 那么我们可以定义一个名为 ...