python学习之 getattr vs __get__ vs __getattr __ vs __getattribute__ vs __getitem__
1. getattr、setattr、hasattr
getattr比较常用,与setattr和hasattr一起出现,他们也是最容易理解的,下面是他的用法:
- class Profile():
- name="xiaoxin"
def sex(self):- return "male"p=Profile()
- hasattr(p, "name") # 判断属性是否存在
- >>> True
- hasattr(p, "age") # 判断属性是否存在
- >>> False
getattr(p, "name") # 获取属性值
>>> xiaoxin
getattr(p, "sex")
>>> <bound method Profile.sex of <__main__.Profile object at 0x7f22608f9710>>
getattr(p, "age", 14) # 如果属性不存在,则返回默认值
>>> 14- setattr(p, "age", "") # 为属性赋值,并没有返回值
- hasattr(p, "age") # 属性存在了
- >>> True
2. __get__ 、 __set__、 __delete__
提起__get__, 就不能不说 __set__, __delete__ , 一个类,只要其内部定义了方法 __get__, __set__, __delete__ 中的一个或多个,就可以称其为描述符。如果同时定义了__get__()
和__set__()
,其被认为是一个数据描述符。只定义__get__()
的描述符被称为非数据描述符。
描述符常被用来作类型检查, 下面看它的具体用法:
- class Integer:
- def __init__(self, name):
- self.name = name
- def __get__(self, instance, owner):
if instance is None:- return self
- else:
- return instance.__dict__[self.name]
- def __set__(self, instance, value):
if not isinstance(value, int):- raise TypeError('excepted an int')
- instance.__dict__[self.name] = value
- def __delete__(self, instance):
del instance.__dict__[self.name]- class Point:
- x = Integer('x')
- y = Integer('y')
- def __init__(self, x, y):
- self.x = x
- self.y = y
- p = Point(2, 3)
p.x
>> 2
p.y
>> 3
p = Point(2.5, 3)
>> TypeError: excepted an int
需要注意的是,对象属性的访问顺序:实例属性>类属性>父类属性>__getattr__(),当Python解释器发现实例对象的字典中,有与描述符同名的属性时,描述符优先,会覆盖掉实例属性。
3. __getattr__ 、__setattr__ 、__delattr__
从对象中读取某个属性时,首先需要从self.__dicts__中搜索该属性,如果__dict__中没有该属性, 再从__getattr__中拿到返回值。当设置属性时,则会触发__setattr__方法,在这里可以进行类型验证(描述符只会对定义的描述符属性进行类型验证, 而__setattr__会对所有属性进行类型验证)
- class Point:
- def __init__(self, x, y):
- self.x = x
- self.y = y
- def __getattr__(self, item):
- print(f'getattr {item}')
- return None
- def __setattr__(self, key, value):
- print(f'setattr {key}:{value}')
- if isinstance(value, int):
- return object.__setattr__(self, key, value)
- def __delattr__(self, item):
- print(f"delattr {item}")
- del self.__dict__[item]
- p = Point(2, 3)
>>> setattr x:2
>>> setattr y:3
p.x
>>> 3
p.c
>>> getattr c
>>> None
p.c = 9
>>> setattr c:9
p.c
>>> 9
4. __getattribute__
无论调用属性还是方法,都是先强制调用 __getattribute__ 方法,然后再传回属性的值或者是 函数(方法)的引用。
- class Point:
- def __init__(self, x, y):
- self.x = x
- self.y = y
- def __getattribute__(self, item): # 在 __getattribute__ 方法里面不要在出现self.**这种调用,因为每次调用类的属性都会强制调用 __getattribute__ ,会造成递归调用
- return 'i get you ' if item == 'x' else object.__getattribute__(self, item)
- def __getattr__(self, item):
- print(f'getattr {item}')
- return None
- p = Point(2, 3)
p.x
>>> i get you
p.y
>>> 3
p.c # 首先调用 __getattribute__ , 里面实现了 查找__dict__里面有没有这个键,如果没有再调用 __getattr__方法
>>> getattr c
>>> None
5. __getitem__、__setitem__、__delitem__
这三个方法主要用于对集合的操作
可变集合需要实现: __len__ __getitem__ __setitem__ __delitem__
不可变集合需要实现: __len__ __getitem__
__len__:返回集合长度
__getitem__(self, item) 使用索引访问元素
__setitem__(self, key, value) 对索引赋值,使用 self[key] = value 。
__delitem__(self, key) 删除索引值 del self[key]
__contains__ 实现in运算符,如果没有实现这个方法python也会调用__getitem__来使in运算符可用
- class TemTest:
- def __init__(self,):
- self.x = [i for i in range(10)]
- def __len__(self):
- return len(self.x)
- def __getitem__(self, item):return self.x[item]
- def __setitem__(self, key, value):
- self.x[key] = value
- def __delitem__(self, key):
- del self.x[key]
- def __contains__(self, item):
- return item in self.x
- def __repr__(self):
- return '{}'.format(self.x)
- test=TemTest() #实例化
- print(len(test)) #返回长度
- print(test[0]) #打印下标0的值
- print(test[:3]) #切片
- test[3]=10 #将下标3的值替换为10
- print(test)
- del test[3] #删除下标3的值
- print(test)
- print(1 in test) #测试in运算符
- print(3 in test)
- 10
- 0
- [0, 1, 2]
- [0, 1, 2, 10, 4, 5, 6, 7, 8, 9]
- [0, 1, 2, 4, 5, 6, 7, 8, 9]
- True
- False
参考博文:https://www.cnblogs.com/flashBoxer/p/9645939.html
python学习之 getattr vs __get__ vs __getattr __ vs __getattribute__ vs __getitem__的更多相关文章
- 小甲鱼Python学习笔记
一 isdigit()True: Unicode数字,byte数字(单字节),全角数字(双字节),罗马数字False: 汉字数字Error: 无 isdecimal()True: Unicode数字, ...
- python的反射函数(hasattr()、getattr()、setattr()与delattr())和类的内置属性attr(__getattr()__、__setattr()__与__delattr()__)
主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省),有四个可以实现自省函数. hasattr(object,name) 判断object中是否有name字符串对应的属性或方法,返回Tr ...
- Python学习笔记之类与对象
这篇文章介绍有关 Python 类中一些常被大家忽略的知识点,帮助大家更全面的掌握 Python 中类的使用技巧 1.与类和对象相关的内置方法 issubclass(class, classinfo) ...
- Python学习笔记之常用函数及说明
Python学习笔记之常用函数及说明 俗话说"好记性不如烂笔头",老祖宗们几千年总结出来的东西还是有些道理的,所以,常用的东西也要记下来,不记不知道,一记吓一跳,乖乖,函数咋这么多 ...
- Python学习记录day6
title: Python学习记录day6 tags: python author: Chinge Yang date: 2016-12-03 --- Python学习记录day6 @(学习)[pyt ...
- 记录Python学习中的几个小问题
记录Python学习中的几个小问题,和C#\JAVA的习惯都不太一样. 1.Django模板中比较两个值是否相等 错误的做法 <option value="{{group.id}}&q ...
- 《Python学习手册》读书笔记
之前为了编写一个svm分词的程序而简单学了下Python,觉得Python很好用,想深入并系统学习一下,了解一些机制,因此开始阅读<Python学习手册(第三版)>.如果只是想快速入门,我 ...
- Python:Python学习总结
Python:Python学习总结 背景 PHP的$和->让人输入的手疼(PHP确实非常简洁和强大,适合WEB编程),Ruby的#.@.@@也好不到哪里(OO人员最该学习的一门语言). Pyth ...
- Python学习的个人笔记(基础语法)
Python学习的个人笔记 题外话: 我是一个大二的计算机系的学生,这份python学习个人笔记是趁寒假这一周在慕课网,w3cschool,还有借鉴了一些博客,资料整理出来的,用于自己方便的时候查阅, ...
随机推荐
- 野指针与'关键字'NULL
野指针与'关键字'NULL 一.NULL是什么? 在C/C++中的标准定义: #ifdef __cplusplus //条件编译,判断是c++还是c环境 #define NULL 0 //c++环境 ...
- timers模块
timers模块 var timers = require('timers'); function A() { //将A对象注册到定时器里 timers.enroll(); //进行激活,如果不激活, ...
- 四。Hibernate 使用MAVEN工具
maven工具的使用1.作用:打包项目以及jar包的版本管理2.使用步骤: a.下载maven工具,修改conf目录下的setting.xml文件 <mirror> <id>a ...
- 类Date
概述: java.util.Date类 表示特定的瞬间,精确到毫秒.毫秒就是千分之一秒.继续查阅API,发现Date拥有多个构造函数,只是部分已经过时,但是其中有未过时的构造函数可以把毫秒值转成日期对 ...
- Playfair 加密
题目真的好长但是意思很简单 89.加密 (15分)C时间限制:3 毫秒 | C内存限制:3000 Kb题目内容:一种Playfair密码变种加密方法如下:首先选择一个密钥单词(称为pair)(字母不重 ...
- php框架之phalcon
1.开发助手 1) 下载 git clone https://github.com/phalcon/cphalcon.git git clone https://github.com/phalcon/ ...
- svg-sprite使用
chainWebpack(config) { config.module .rule('svg') .exclude.add(path.resolve(__dirname,'src/assets/ic ...
- filebeat-6.4.3-windows-x86_64输出Kafka
配置filebeat.yml文件 filebeat.prospectors: - type: log encoding: utf- enabled: true paths: - e:\log.log ...
- linux定时备份学习笔记
1.iterm2链接远程中文乱码 shh端vi ~/.bash_profile export LC_CTYPE=en_US.UTF-8 source ~/.bash_profile 2.WARNI ...
- Python——pyqt5——各框架编程
一.日期时间(dateTimeEdit/dateEdit) setDateTime:设置日期(含时间) QDateTime.currentDateTime():当前日期(含时间) setDate:设置 ...