python魔法方法:__getattr__,__setattr__,__getattribute__

难得有时间看看书。。。。静下心来好好的看了看Python。。其实他真的没有自己最开始想的那么简单吧:

首先来看看上述三个魔法方法的定义吧:

(1)__getattr__(self, item):

在访问对象的item属性的时候,如果对象并没有这个相应的属性,方法,那么将会调用这个方法来处理。。。这里要注意的时,假如一个对象叫fjs,  他有一个属性:fjs.name = "fjs",那么在访问fjs.name的时候因为当前对象有这个属性,那么将不会调用__getattr__()方法,而是直接返回了拥有的name属性了

(2)__setattr__(self, item, value):

当试图对象的item特性赋值的时候将会被调用。。

(3)__getattribute__(self, item):

这个只有在新式类中才有的,对于对象的所有特性的访问,都将会调用这个方法来处理。。。可以理解为在__getattr__之前

嗯。。。有了这几个方法就可以干很多很多的事情了。。。例如拦截器啥的。。。动态代理啥的。。。很方便就能实现了。。。起码比用java实现类似的功能方便多啦。。。。

不过需要注意的时候,在重写这些方法的时候需要特别的小心,因为容易引起循环调用。。。。

这里先来举一个例子,用于实现拦截所有的特性访问,在访问的时候打log啥的:

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

上述代码的输出如下:

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

很简单就实现了拦截的功能吧。。。而且这里可以知道__getattribute__方法拦截了属性和方法的访问。。这里也就是所谓的所有的特性的访问了。。不过要注意的是:__getattribute__只有在新式类中才能用的。。。

嗯。。接下来配合使用__getattr__和__getattribute__来实现一个非切入式的编程:

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

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

最后,关于__setattr__()方法,这个就不细说了。。。不过他的使用还需要特别注意一些。。因为稍不注意就容易陷入循环调用了。。。。

python魔法方法:__getattr__,__setattr__,__getattribute__的更多相关文章

  1. Python魔法方法__getattr__和__getattribute__详解

    在Python中有这两个魔法方法容易让人混淆:__getattr__和getattribute.通常我们会定义__getattr__而从来不会定义getattribute,下面我们来看看这两个的区别. ...

  2. python 魔法方法补充(__setattr__,__getattr__,__getattribute__)

    python 魔法方法补充 1 getattribute (print(ob.name) -- obj.func())当访问对象的属性或者是方法的时候触发 class F(object): def _ ...

  3. python魔法方法大全

    1.python魔法方法详解: python魔法方法是可以修改重载的,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而 ...

  4. 1. Python 魔法方法

    Python 魔法方法 基础: 如果你想... 所以,你写... Python调用... 初始化一个实例 x = MyClass() x.__init__() 作为一个字符串的"官方&quo ...

  5. with上下文管理 python魔法方法

    with语法在Python里很常见, 主要的利好是使用代码更简洁. 常见的使用场景有: 1. 资源对象的获取与释放. 使用with可以简化try...finally ... 2. 在不修改函数代码的前 ...

  6. Python魔法方法总结及注意事项

    1.何为魔法方法: Python中,一定要区分开函数和方法的含义: 1.函数:类外部定义的,跟类没有直接关系的:形式: def func(*argv): 2.方法:class内部定义的函数(对象的方法 ...

  7. python 魔法方法诠释

    什么是Python魔法方法 什么是魔法方法呢?它们在面向对象的Python的处处皆是.它们是一些可以让你对类添加"魔法"的特殊方法. 它们经常是两个下划线包围来命名的(比如 ini ...

  8. Python魔法方法之属性访问 ( __getattr__, __getattribute__, __setattr__, __delattr__ )

    通常情况下,我们在访问类或者实例对象的时候,会牵扯到一些属性访问的魔法方法,主要包括: ① __getattr__(self, name): 访问不存在的属性时调用 ② __getattribute_ ...

  9. python中的__getattr__、__getattribute__、__setattr__、__delattr__、__dir__

    __getattr__:     属性查找失败后,解释器会调用 __getattr__ 方法. class TmpTest: def __init__(self): self.tmp = 'tmp12 ...

随机推荐

  1. 洛谷P2054 [AHOI2005]洗牌(扩展欧几里德)

    洛谷题目传送门 来个正常的有证明的题解 我们不好来表示某时刻某一个位置是哪一张牌,但我们可以表示某时刻某一张牌在哪个位置. 设数列\(\{a_{i_j}\}\)表示\(i\)号牌经过\(j\)次洗牌后 ...

  2. 自学Linux Shell12.2-test命令

    点击返回 自学Linux命令行与Shell脚本之路 12.2-test命令 if-then语句不能测试命令退出状态码之外的条件,test命令提供了在if-then语句中测试不同条件的途径. 如果tes ...

  3. HDU 3416 Marriage Match IV (最短路径,网络流,最大流)

    HDU 3416 Marriage Match IV (最短路径,网络流,最大流) Description Do not sincere non-interference. Like that sho ...

  4. react性能检测与优化

    网页运行最重要的是速度快嘛,那我们怎么知道网页运行的时候,哪些部分快哪些部分慢呢? 我们可以安装react性能检测工具进行检测,通过安装 然后修改app/index.jsx文件 ,在要检测的组件运行之 ...

  5. MATLAB:图像选取局部区域滤波(roicolor、roipoly、roifill、fspecial、roifilt2函数)

    对于某些特殊的图像处理,我们不希望将整张图都进行图像处理.这个时候就用到了roicolor.roipoly.roifill.fspecial.roifilt2函数.代码实现过程如下: close al ...

  6. vue2.0 keep-alive最佳实践

    1.基本用法 vue2.0提供了一个keep-alive组件用来缓存组件,避免多次加载相应的组件,减少性能消耗 <keep-alive> <component> <!-- ...

  7. 线程优先级.Priority()

    线程对象.Priority(),线程优先级1-10,10优先级最高.此功能比较鸡肋,不起作用.了解即可 以下案例:循环输出加减乘除,除优先级最高 //MyThread线程 class MyThread ...

  8. ffmpeg基本用法

    FFmpeg FFmpeg 基本用法 本课要解决的问题 1.FFmpeg的转码流程是什么? 2.常见的视频格式包含哪些内容吗? 3.如何把这些内容从视频文件中抽取出来? 4.如何从一种格式转换为另一种 ...

  9. raise TemplateDoesNotExist

    raise TemplateDoesNotExist(template_name, chain=chain)django.template.exceptions.TemplateDoesNotExis ...

  10. grafana配置

    grafana配置 官网介绍:http://docs.grafana.org/installation/configuration/ 以deb或者rpm安装的,则默认的配置文件是/etc/grafan ...