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

# -*- coding: utf- -*-
class Fjs(object):
def __init__(self, name):
self.name = name def hello(self):
print "said by : ", self.name def __getattribute__(self, item):
print "访问了特性:" + item
return object.__getattribute__(self, item) fjs = Fjs("fjs")
print fjs.name
fjs.hello()

输出:

访问了特性:name
fjs
访问了特性:hello
said by : 访问了特性:name
fjs

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

# -*- coding: utf- -*-
class Fjs(object):
def __init__(self, name):
self.name = name def hello(self):
print "said by : ", self.name def fjs(self, name):
if name == self.name:
print "yes"
else:
print "no" class Wrap_Fjs(object):
def __init__(self, fjs):
self._fjs = fjs def __getattr__(self, item):
if item == "hello":
print "调用hello方法了"
elif item == "fjs":
print "调用fjs方法了"
return getattr(self._fjs, item) fjs = Wrap_Fjs(Fjs("fjs"))
fjs.hello()
fjs.fjs("fjs")

输出:

调用hello方法了
said by : fjs
调用fjs方法了
yes

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

# -*- coding: utf- -*-
class Fjs(object):
def __init__(self, name):
self.name = name def hello(self):
print "said by : ", self.name def fjs(self, name):
if name == self.name:
print "yes"
else:
print "no" class Wrap_Fjs(Fjs):
def __init__(self, fjs):
self._fjs = fjs def __getattr__(self, item):
if item == "hello":
print "调用hello方法了"
elif item == "fjs":
print "调用fjs方法了"
return getattr(self._fjs, item) fjs = Wrap_Fjs(Fjs("fjs"))
fjs.hello()
fjs.fjs("fjs")

输出:

said by :  fjs
yes

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

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

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

class ObjectDict(dict):
def __init__(self, *args, **kwargs):
super(ObjectDict, self).__init__(*args, **kwargs) def __getattr__(self, name):
value = self[name]
if isinstance(value, dict):
value = ObjectDict(value)
return value if __name__ == '__main__':
od = ObjectDict(asf={'a': }, d=True)
print od.asf, od.asf.a # {'a': }
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. Fresco 获得Bitmap

    ImageRequest imageRequest = ImageRequestBuilder .newBuilderWithSource( Uri.parse(getFeedItem(positio ...

  2. python操作json数据格式--基础

    非常基础的json库的用法,后续添加数据格式.编码等内容 参考文章 json进阶 Python的json模块提供了一种很简单的方式来编码和解码JSON数据. 其中两个主要的函数是 json.dumps ...

  3. Error:Unable to make the module:***, related gradle configuration was not found. Please, re-import the Gradle project and try again.

    打开idea的 View -> Tool Windows -> Gradle.然后点击 Refresh

  4. Linux中磁盘还有空间,但创建文件时提示空间不足

    首先需要知道创建文件时,需要满足两个条件:1.磁盘上还有空间:2.inode号还有剩余. 这两个条件可以分别使用"df -h"以及"df -i"查看使用情况 [ ...

  5. javascript类型系统

    前面的话 除了对象之外,数组Array类型可能是javascript中最常用的类型了.而且,javascript中的数组与其他多数语言中的数组有着相当大的区别.本文将介绍javascript中的数组A ...

  6. POWEROJ 2610 判断回文串 【HASH】

    题目链接[https://www.oj.swust.edu.cn/problem/show/2610] 题意:给你一个字符串,让你判断这个字符串是不是回文串,字符串的长度是1<len<1e ...

  7. 51Nod1802 左偏树计数

    题目大意 求$n$个点的无标号左偏树个数 既然你都点进来了,那么估计也是奔着题解来的.... 废话少说.... 首先,左偏树有这么一些性质 设最右链长度为$r[p]$ 1.左偏树的子树仍然是左偏树 2 ...

  8. 【20181023T3】“新”的家园【虚图】

    打死也不告诉你这个名字是我编的 题面 [错解] 哎最短路欸 哎floyd+dijkstra有30分 骗分骗分 [正解] 我们发现n和m(不是E)不是一个数量级的 也就是说,在做传统最短路的时候,很多时 ...

  9. 如何解决The underlying provider failed on Open问题

    转自codeproject,找了半天解决办法,这个最靠谱. 我数据库用的EF做ORM,在vs里面测试的时候不会出现这个错误,用IIS就出错了.解决方法如下 Solution for "The ...

  10. bzoj 1779

    较水的网络流. /************************************************************** Problem: 1779 User: idy002 L ...