Python之属性、特性和修饰符
作为面对对象的核心内容,将从以下一个方面进行总结:
1. property和@property
2. __getattribute__()、__getattr__()、__setattr__()、__delattr__()
3. 描述符__get__()、__set__()、__delete__()
4. 不可变对象的实现
1. property和@property
还是直接上代码来的方便
property()用法
#coding = utf-8 class property_test:
def __init__(self, size=10):
self.size=size def __getsize__(self):
return self.size def __setsize__(self, value):
self.size = value def __deletesize__(self): del self.size x= property(__getsize__, __setsize__, __deletesize__) if __name__ == "__main__":
p = property_test()
p.x = 20
print (p.size) >>> 20
@property用法
#coding = utf-8 '''class property_test:
def __init__(self, size=10):
self.size=size def __getsize__(self):
return self.size def __setsize__(self, value):
self.size = value def __deletesize__(self): del self.size x= property(__getsize__, __setsize__, __deletesize__) ''' class property_test:
def __init__(self, size=10):
self.sizevalue=size #特别注意sizevalue不要和size同名 @property
def size(self):
return self.sizevalue @size.setter
def size(self, value):
self.sizevalue = value @size.deleter
def size(self):
del self.sizevalue if __name__ == "__main__":
p = property_test()
p.size = 20
p.size += 20
print (p.size, p.sizevalue)
2. __getattribute__()、__getattr__()、__setattr__()、__delattr__()
属性查找过程:
__getattribute__ >>>> __dict__ >>>> __slots__ >>>> __getattr__
主要注意__getattr__的用法和无限递归错误
__getattr__在实例以及对应的__dict__中查找属性失败,那么会调用__getattr__函数
防止无限递归错误可以使用以下两种方法:
1. self.__dict__[name] = value
2. super().__setattr__(name,value)
例:
class rectange:
def __init__(self, width=20, height=40):
self.width = width
self.height = height def __getattr__(self, name):
return self.width def __setattr__(self,name, value):
if name == "squ":
super().__setattr__(name,value)
super().__setattr__("width",40)
super().__setattr__("height",40)
print (name, self.__dict__[name])
else:
#self.__dict__[name] = value
super().__setattr__(name,value)
print (name, self.__dict__[name]) if __name__ == "__main__":
p = rectange()
p.width = 10
p.squ = 80
print (p.width, p.height)
3. 描述符
描述符说的直白点就是一个“绑定行为”的对象属性,通过__get__()、__set__()和__delete__()函数重写描述符属性
如果上述方法被定义在一个对象中,那么这个对象就是一个描述符
当定义拥有者类时,每个修饰符对象都是修饰符类的实例,绑定在类级别的属性上
方法的原型为:
① __get__(self, instance, owner)
② __set__(self, instance, value)
③ __del__(self, instance)
class A:
def __init(self):
self.color = "red" def __get__(self, instance, owner):
print ("get instance:", instance)
print ("get owner:", owner)
return self.color def __set__(self, instance, value): print ("set instance:", instance)
print ("set value:", value)
self.color = value def __delete__(self, instance): print ("delete instance:", instance)
del self.color class B:
a = A()
def __init__(self):
self.color = "black" if __name__ == "__main__":
b = B()
b.a = "blue"
b.color = b.a
del b.a
4. 使用__slots__实现不可变对象
首先说明下__slots__方法,具体可以查看https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0013868200605560b1bd3c660bf494282ede59fee17e781000
方法:
1. 把__slots__设为唯一允许操作的属性,这会使得对象内部的__dict__不再有效并阻止对其他属性的访问
2. 在__init__中调用基类的__setattr__实现
3. 在__setattr__中抛出异常
例:
#coding=utf-8 class student:
__slots__ = ("name") def __init__(self, name):
super().__setattr__("name", name)
self.name = name
print (self.name) def __str__(self):
return "{0.name}".format(self) def __setattr__(self, name, value):
raise Exception(" '{__class__.__name__}' has no\
attribute '{name}'".format(__class__=self.__class__,name=self.name)) if __name__ == "__main__":
s = student("zhanglin")
#s.name = "lizhi"
__slot__定义类中可以被外界访问的属性,类似node中的exports。
当父类中定义了__slot__时,不能向父类中添加属性。如果子类中没有定义__slot__,则子类不受父类__slot__定义的限制。
如果父类与子类中都定义了__slot__,则影响的结果为父类与子类__slot__的合集。
最新文章
- SPSS数据分析—广义线性模型
- 【转】ListView学习笔记(二)——ViewHolder
- 华清远见金牌讲师名家大讲堂Android开发篇成功举办
- 基于Open vSwitch搭建虚拟路由器
- andriod 动态创建控件
- 20145222黄亚奇《Java程序设计》第5周学习总结
- easyui datagrid 学习
- Hough 变换
- GWT工程架构分析与理解
- 使用Fragment实现类似TabHost标签栏的效果
- MVC小系列(二十一)【带扩展名的路由可能失效】
- 执行configure报错configure: error: C++ preprocessor ";/lib/cpp"; fails sanity check
- PMP考试的过与只是
- Java 反射 Class对象
- zlib1.2.11静态编译
- 2017C语言程序设计预备作业
- Java调用SQL脚本执行的方案
- Win10蓝屏的一些解决办法
- June. 24th 2018, Week 26th. Sunday
- asp.net 简单记录请求的客户端和服务端 处理时间
热门文章
- java 怎么让打印信息换行?
- [Cannot deserialize JSON array into type] NewtonSoft.Json解析数据出错原因
- CSS 初级攻略
- P4949 最短距离(基环树+树链剖分)
- 新机git及github sshkey简单配置
- 解决Vim插入模式下backspace按键无法删除字符的问题【转】
- [USACO08DEC]在农场万圣节Trick or Treat on the Farm
- LeetCode——Next Greater Element I
- postman(谷歌) httprequester(火狐)
- Pandas描述性统计