引言:

1.object.__getattr__(self, name)
当一般位置找不到attribute的时候,会调用getattr,返回一个值或AttributeError异常。

2.object.__getattribute__(self, name)
无条件被调用,通过实例访问属性。如果class中定义了__getattr__(),则__getattr__()不会被调用(除非显示调用或引发AttributeError异常)

3.object.__get__(self, instance, owner)
如果class定义了它,则这个class就可以称为descriptor。owner是所有者的类,instance是访问descriptor的实例,如果不是通过实例访问,而是通过类访问的话,instance则为None。(descriptor的实例自己访问自己是不会触发__get__,而会触发__call__,只有descriptor作为其它类的属性才有意义。)(所以下文的d是作为C2的一个属性被调用)

示例1:

# __getattribute__、__getattr__、__get__
class C(object):
a = 'abc' def __getattribute__(self, *args, **kwargs):
print("__getattribute__() is called")
return object.__getattribute__(self, *args, **kwargs) def __getattr__(self, name):
print("__getattr__() is called ")
return name + " from getattr" def __get__(self, instance, owner):
print("__get__() is called", instance, owner)
return self def foo(self, x):
print(x) class C2(object):
d = C() if __name__ == '__main__':
c = C()
c2 = C2()
print(c.a)
# __getattribute__() is called
# abc
print(c.b)
# __getattribute__() is called
# __getattr__() is called
# b from getattr
c2.d
# __get__() is called <__main__.C2 object at 0x0000007D8B0E7D68> <class '__main__.C2'>
print(c2.d.a)
# __get__() is called <__main__.C2 object at 0x000000B6FDAE7D68> <class '__main__.C2'>
# __getattribute__() is called
# abc

示例2:

class LazyProperty:

    def __init__(self, method):
print(method,method.__name__)
self.method = method
self.method_name = method.__name__
# print('function overriden: {}'.format(self.method))
# print("function's name: {}".format(self.method_name)) def __get__(self, obj, cls):
print('__get__',obj,cls)
if not obj:
return None
value = self.method(obj)
# print('value {}'.format(value))
setattr(obj, self.method_name, value)
return value class Jefrey: def __init__(self):
self.x = 'foo'
self.y = 'bar'
self._resource = None @LazyProperty
def resource(self):
print('initializing self._resource which is: {}'.format(self._resource))
self._resource = tuple(range(5)) # 代价大的
return self._resource def main():
t = Jefrey()
# <function Jefrey.resource at 0x00000089690E6730> resource
print(t.x)
print(t.y)
# foo
# bar
# 做更多的事情。。。
print(t.resource)
# __get__ <__main__.Jefrey object at 0x00000089690E7C50> <class '__main__.Jefrey'>
# initializing self._resource which is: None
# (0, 1, 2, 3, 4)
print(t.resource)
# (0, 1, 2, 3, 4) if __name__ == '__main__':
main()

  

Python开发【笔记】: __get__和__getattr__和__getattribute__区别的更多相关文章

  1. python开发笔记-通过xml快捷获取数据

    今天在做下python开发笔记之如何通过xml快捷获取数据,下面以调取nltk语料库为例: import nltk nltk.download() showing info https://raw.g ...

  2. python开发笔记-python调用webservice接口

    环境描述: 操作系统版本: root@9deba54adab7:/# uname -a Linux 9deba54adab7 --generic #-Ubuntu SMP Thu Dec :: UTC ...

  3. 飘逸的python - __get__ vs __getattr__ vs __getattribute__以及属性的搜索策略

    差别: __getattribute__:是无条件被调用.对不论什么对象的属性訪问时,都会隐式的调用__getattribute__方法,比方调用t.__dict__,事实上运行了t.__getatt ...

  4. python开发笔记-Python3.7+Django2.2 Docker镜像搭建

    目标镜像环境介绍: 操作系统:ubuntu16.04 python版本:python 3.7.4 django版本:2.2 操作步骤: 1.  本地安装docker环境(略)2. 拉取ubunut指定 ...

  5. python开发笔记之zip()函数用法详解

    今天分享一篇关于python下的zip()函数用法. zip()是Python的一个内建函数,它接受一系列可迭代的对象作为参数,将对象中对应的元素按顺序组合成一个tuple,每个tuple中包含的是原 ...

  6. Python开发笔记之正则表达式的使用

    查找正则表达式 import re re_txt = re.compile(r'(\d)*.txt') m = re_txt.search(src) if not m == None: m.group ...

  7. python开发笔记-类

    类的基本概念: 问题空间:问题空间是问题解决者对一个问题所达到的全部认识状态,它是由问题解决者利用问题所包含的信息和已贮存的信息主动的地构成的. 初始状态:一开始时的不完全的信息或令人不满意的状况: ...

  8. Python开发笔记之-浮点数传输

    操作系统 : CentOS7.3.1611_x64 gcc版本 :4.8.5 Python 版本 : 2.7.5 思路如下 : 1.将浮点数a通过内存拷贝,赋值给相同字节的整型数据b: 2.将b转换为 ...

  9. Python开发笔记:网络数据抓取

    网络数据获取(爬取)分为两部分: 1.抓取(抓取网页) · urlib内建模块,特别是urlib.request · Requests第三方库(中小型网络爬虫的开发) · Scrapy框架(大型网络爬 ...

随机推荐

  1. wcf实体和ef实体冲突。。。

    指定的架构无效.错误: CLR 类型到 EDM 类型的映射不明确,因为多个 CLR 类型与 EDM 类型“agentinfo”匹配.以前找到的是 CLR 类型“chanchengFlow.Models ...

  2. 【Java面试题】44 java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?

    字节流,字符流.字节流继承于InputStream OutputStream,字符流继承于InputStreamReader OutputStreamWriter.在java.io包中还有许多其他的流 ...

  3. 调用外部 DLL 中的函数(2. 晚绑定)

    , b, t, );end; procedure TForm1.FormDestroy(Sender: TObject);begin  FreeLibrary(inst);  {记得释放}end; e ...

  4. 第二章 入门(MyBatis)

    本章将会以简略的步骤告诉你如何安装和创建 MyBatis-Spring,并构建一个简单的数据访问事务性的应用程序. Installation 要使用 MyBatis-Spring 模块,你只需要包含 ...

  5. CSS清除浮动常用方法小结

    1.使用空标签清除浮动.我用了很久的一种方法,空标签可以是div标签,也可以是P标签.我习惯用<P>,够简短,也有很多人用<hr>,只是需要另外为其清除边框,但理论上可以是任何 ...

  6. POJ 1273 Drainage Ditches (网络最大流)

    http://poj.org/problem? id=1273 Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Sub ...

  7. 进程 vs. 线程(python的协程)(转廖雪峰老师python教程)

    我们介绍了多进程和多线程,这是实现多任务最常用的两种方式.现在,我们来讨论一下这两种方式的优缺点. 首先,要实现多任务,通常我们会设计Master-Worker模式,Master负责分配任务,Work ...

  8. 在navicat中新建数据库

    前言: 在本地新建一个名为editor的数据库: 过程: 1.: 2.选择:utf8mb4 -- UTF-8 Unicode字符集,原因在于:utf8mb4兼容utf8,且比utf8能表示更多的字符. ...

  9. poj_1743 后缀数组

    题目大意 给定一串数字,长度为N.定义数字中的某个连续的子串为一个"theme",只要子串满足: (1)长度 >= 5 (2)和该子串相同或者该子串的“变种串”在整串数字中出 ...

  10. UVa 130 - Roman Roulette

    模拟约瑟夫环  Roman Roulette  The historian Flavius Josephus relates how, in the Romano-Jewish conflict  o ...