这里的属性即包括属性变量,也包括属性方法。即类的变量和方法。
  当访问某个实例属性时, 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. Zookeeper(二)Zookeeper原理与API应用

    一 Zookeeper概述 1.1 概述 Zookeeper是Google的Chubby一个开源的实现.它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.名字服务. 分布式同步.组服 ...

  2. 【LOJ】#2017. 「SCOI2016」围棋

    题解 考虑到状态数比较复杂,其实我们需要轮廓线dp-- 我们设置\(f[x][y][S][h][k]\)为考虑到第(x,y)个格子,S是轮廓线上的匹配状态,是二进制,如果一位是1表示这一位匹配第一行匹 ...

  3. EditText属性描述

    android:layout_gravity="center_vertical"//设置控件显示的位置:默认top,这里居中显示,还有bottom android:hint=&qu ...

  4. poj2243 Knight Moves(BFS)

    题目链接 http://poj.org/problem?id=2243 题意 输入8*8国际象棋棋盘上的两颗棋子(a~h表示列,1~8表示行),求马从一颗棋子跳到另一颗棋子需要的最短路径. 思路 使用 ...

  5. CodeForces 811B Vladik and Complicated Book

    离线,树状数组. 数据范围好像有点小,直接暴力可以过的. 我直接上了$n,Q≤100000$的做法:只需要判断区间上比$x$小的数字有几个即可,可以对询问进行离线操作,从左到右一个一个数字插入到树状数 ...

  6. Python编程举例-装饰器

    装饰器的通常用途是扩展已定义好的函数的功能 一个浅显的装饰器编程例子 #装饰器函数 def outer(fun): def wrapper(): #添加新的功能 print('验证') fun() r ...

  7. Codeforces Round 548 (Div. 2)

    layout: post title: Codeforces Round 548 (Div. 2) author: "luowentaoaa" catalog: true tags ...

  8. android jni c C++ 实现下载

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha android jni c C++ 实现下载

  9. Nginx 502 Bad Gateway 解决方法

    proxy_next_upstream error timeout invalid_header http_500 http_503;或者尝试设置:large_client_header_buffer ...

  10. ngxin error日志

    日志模块ngx_errlog_module对于支持可变参数平台提供的三个接口 #define ngx_log_error(level, log, ...) \ if ((log)->log_le ...