python __getattr__ & __getattribute__ 学习
实例属性的获取和拦截, 仅对实例属性(instance, variable)有效, 非类属性
getattr: 适用于未定义的属性, 即该属性在实例中以及对应的类的基类以及祖先类中都不存在
1. 动态处理事先未定义的属性, 可更好的实现数据隐藏, 当调用dir(obj)时只会显示初始化定义的正常的属性和方法
getattribute: 对于所有属性的访问都会调用该方法, 当属性不存在时会报错
1. 覆盖该方法之后,任何属性的访问都会调用用户自定义的__getattribute__()方法, 性能上会有所损耗.
- 当两个方法同步被重写, 要么在__getattribute__()中显示调用, 要么是触发AttributeError异常时, getattr()才会被调用
 - 要避免无穷递归调用
 - 如果访问未定义属性, 且在__getattr__中未跑出AttributeError异常或者显性的返回一个值, 则会返回None
 
参考: 编写高质量代码:改善Python程序的91个建议
class Attribute(object):
    def __init__(self, name):
        self.name = name
    def __getattribute__(self, key):
        try:
            print('calling __getattribute__.{key}'.format(key=key))
            # 调用超类
            return super(Attribute, self).__getattribute__(key)
            # return object.__getattribute__(self, key)
        except KeyError:
            return 'default'
        except AttributeError as ex:  # 捕获了该异常就不用调用__getattr__
            print(ex)
    def __getattr__(self, key):
        # 什么时候被调用:
        # 1.当属性不在实例以及基类和祖先类的__dict__
        # 2. 当触发AtrributeError异常时(不仅仅是__getattribute__()引发的 AttributeError),porperty中定义的get()方法也会抛出异常
        print('calling __getattr__.{key}'.format(key=key))
        # return 'default'
测试 property, getattribute, __getattr__调用顺序
class A(object):
    _c = 'test'
    def __init__(self):
        self.x = None
    @property
    def a(self):
        print('using property to access attribute')
        if self.x is None:
            print('return value')
            return 'a'
        else:
            print('error occured')
            raise AttributeError
    @a.setter
    def a(self, value):
        self.x = value
    def __getattribute__(self, name):
        print('using __getattribute__ to access attribute')
        return object.__getattribute__(self, name)
    def __getattr__(self, name):
        print('using __getattr__ to access attribute')
        print('attribute name: ', name)
        return 'b'
if __name__ == '__main__':
    a = Attribute('atest')
    print(a.name)
    print(a.test)
    # 测试 property, __getattribute__, __getattr__调用顺序
    # b = A()
    # print(b.a)
    # print('-'*50)
    # b.a = 10
    # print(b.a)
    # print('-'*50)
    # print(A._c)
defaultdict 和 魔法方法__missing__()
dict中并不存在__missing__()方法, 需要派生子类并重写__missing__()方法
# python 2.5 之前默认要自己重写__missing__方法
# python3以后 __missing__(key) called by __getitem__ for missing key;
class DefaultDict(dict):
    def __init__(self, default_factory, *args, **kwargs):
        super(DefaultDict, self).__init__(*args, **kwargs)
        self.default_factory = default_factory
    def __getitem__(self, key):
        try:
            return dict.__getitem__(self, key)
        except KeyError:
            return self.__missing__(key)    
    def __missing__(self, key):
        self[key] = value = self.default_factory()
        return value
												
											python __getattr__ & __getattribute__ 学习的更多相关文章
- Python中__get__, __getattr__, __getattribute__的区别及延迟初始化
		
本节知识点 1.__get__, __getattr__, __getattribute__的区别 2.__getattr__巧妙应用 3.延迟初始化(lazy property) 1.__get__ ...
 - Python - __getattr__和__getattribute__的区别
		
传送门 https://docs.python.org/3/reference/datamodel.html#object.__getattr__ https://docs.python.org/3/ ...
 - Python 装饰器学习
		
Python装饰器学习(九步入门) 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...
 - Requests:Python HTTP Module学习笔记(一)(转)
		
Requests:Python HTTP Module学习笔记(一) 在学习用python写爬虫的时候用到了Requests这个Http网络库,这个库简单好用并且功能强大,完全可以代替python的标 ...
 - 从Theano到Lasagne:基于Python的深度学习的框架和库
		
从Theano到Lasagne:基于Python的深度学习的框架和库 摘要:最近,深度神经网络以“Deep Dreams”形式在网站中如雨后春笋般出现,或是像谷歌研究原创论文中描述的那样:Incept ...
 - Comprehensive learning path – Data Science in Python深入学习路径-使用python数据中学习
		
http://blog.csdn.net/pipisorry/article/details/44245575 关于怎么学习python,并将python用于数据科学.数据分析.机器学习中的一篇非常好 ...
 - (转载)Python装饰器学习
		
转载出处:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方 ...
 - python网络爬虫学习笔记
		
python网络爬虫学习笔记 By 钟桓 9月 4 2014 更新日期:9月 4 2014 文章文件夹 1. 介绍: 2. 从简单语句中開始: 3. 传送数据给server 4. HTTP头-描写叙述 ...
 - Python装饰器学习
		
Python装饰器学习(九步入门) 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 ? 1 2 3 4 5 6 7 8 # -*- ...
 
随机推荐
- SDN实验2
			
第二次sdn实验: 1. 利用mininet创建如下拓扑,要求拓扑支持OpenFlow 1.3协议,主机名.交换机名以及端口对应正确,请给出拓扑Mininet执行结果,展示端口连接情况. 本次使用py ...
 - RedHat linux服务器安装elasticsearch且设置公网访问
			
0. 首先需要安装jdk,因为elasticsearch是Java写的,默认需要Java环境,且安装elasticsearch 7.x需要使用jdk 1.8或更高版本 1. 执行以下命令,创建elas ...
 - jenkins pipeline使用方式
			
pipeline 使用 使用groovy的一种DSL语言,流程控制 pipeline脚本同其他脚本语言一样,从上到下顺序执行,它的流程控制取决于Groovy表达式,为jenkins用户提供了更巨大的灵 ...
 - SpringBoot 应用篇之从 0 到 1 实现一个自定义 Bean 注册器
			
191213-SpringBoot 应用篇之从 0 到 1 实现一个自定义 Bean 注册器 我们知道在 spring 中可以通过@Component,@Service, @Repository 装饰 ...
 - Redis Desktop Manager 0.9.3 版本下载
			
因为Redis Desktop Manager作者在 0.9.4 版本之后选择对所有的安装包收费,不再提供安装包下载,但是源码依旧公开.链接:https://pan.baidu.com/s/1SXsy ...
 - Django 路由name使用
			
Django 路由name使用 name:对URL路由关系进行命名 ***以后可以根据此名称生成自己想要的URL*** # 路由 url 三种形式 url(r'^index/', views.inde ...
 - 近3年常考的Spring面试题及答案
			
1. 一般问题 1.1. 不同版本的 Spring Framework 有哪些主要功能? Version Feature Spring 2.5 发布于 2007 年.这是第一个支持注解的版本. Spr ...
 - java面试经常涉及到的
			
需要掌握的Java知识点: 1 基本数据类型.循环控制.String类型的使用.数组.类和对象.接口和抽象类.面向对象三大特征.异常处理.集合类(List.Map.Set) 2 能够熟练使用Sprin ...
 - [Linux] - 服务器/VPS一键检测带宽、CPU、内存、负载、IO读写
			
一.SuperBench.sh VPS/服务器一键检测带宽.CPU.内存.负载.IO读写等的脚本: wget -qO- https://raw.githubusercontent.com/oooldk ...
 - [其它]iOS 13 正式版发布 iPhone 6s或更新型号均可升级
			
苹果今天(2019.09.20)发布了 iOS 13 正式版,可以升级的设备包括 iPhone 6s 或更新型号.第七代 iPod Touch. iOS 13 推出深色模式,为 iPhone 带来截然 ...