Python属性、方法和类管理系列之----__slots__属性
一句话说明
__slots__是用来限制实例的属性的,__slots__可以规定实例是否应该有__dict__属性;__slots__不能限制类的属性。
只有__slots__列表内的这些变量名可赋值为实例属性。
class A:
__slots__=['name']
def __init__(self):
self.name='js'
self.age=22
a=A()
运行结果:
Traceback (most recent call last):
File "a.py", line 6, in <module>
a=A()
File "a.py", line 5, in __init__
self.age=22
AttributeError: 'A' object has no attribute 'age'
__slots__只是限制实例,对类对象没有影响
class A:
__slots__=['name','city']
age=22
def __init__(self):
self.name='js'
a=A()
print('A __slots__: ', A.__slots__)
print('a __slots__: ', a.__slots__)
print('A __dict__: ', A.__dict__)
print('a __dict__: ', a.__dict__)
运行结果如下:
A __slots__: ['name', 'city']
a __slots__: ['name', 'city']
#事实上,所有定义在__slots__中的属性都会放置在类的__dict__当中,即使没有使用的属性(city)也是如此。
#而当实例需要取对象时,总是会先到类的__dict__中进行检查,如果类的__dict__中的属性是一个对象且该对象对属性的读取做了一些限制,那么就会直接影响到实例是否能够调用该属性。__slots__的工作原理是如此,后面介绍的描述符类亦是如此。
#在类的__dict__中,也会存入__slots__属性。
A __dict__: {'age': 22, '__init__': <function A.__init__ at 0x7f2ae9be67b8>, 'name': <member 'name' of 'A' objects>, 'city': <member 'city' of 'A' objects>, '__slots__': ['name', 'city'], '__module__': '__main__', '__doc__': None}
#当我们试图调用a.__dict__时,出现错误,因为该属性没有出现在__slots__中,所以禁止赋值或者访问。
Traceback (most recent call last):
File "a.py", line 10, in <module>
print('a __dict__: ', a.__dict__)
AttributeError: 'A' object has no attribute '__dict__'
可以同时存在__slots__和__dict__吗?
可以,如果把__dict__属性存入__slots__中,那么就允许使用__dict__属性了。
这时,如果所有__slots__中定义的属性存在__slots__中,如果没有定义的属性,那么存在__dict__中,从而实现属性的分别管理。
dir函数获取所有定义在__slots__和__dict__中的属性。或者通过list(getattr(X, 'dict', [])) + getattr(X, 'slots', [])来得到所有的属性。
class A:
__slots__=('name','city','__dict__')
def __init__(self):
self.name='js'
self.age=22
a=A()
print('A __slots__: ', A.__slots__)
print('a __slots__: ', a.__slots__)
print('A __dict__: ', A.__dict__)
print('a __dict__: ', a.__dict__)
运行结果如下:
A __slots__: ('name', 'city', '__dict__')
a __slots__: ('name', 'city', '__dict__')
#连__dict__都会保存在类的__dict__中,且属性值是一个object。
A __dict__: {'city': <member 'city' of 'A' objects>, 'name': <member 'name' of 'A' objects>, '__module__': '__main__', '__doc__': None, '__init__': <function A.__init__ at 0x7f540bb787b8>, '__slots__': ('name', 'city', '__dict__'), '__dict__': <attribute '__dict__' of 'A' objects>}
#由于现在age没有出现在__slots__中,且允许存在__dict__,所以属性age出现在实例本身的__dict__中。
a __dict__: {'age': 22}
如果子类中没有__slots__,但是超类中有...
class Super:
__slots__=['name']
pass
class Sub(Super):
def __init__(self):
self.name='js'
self.age=22
a=Sub()
print('Sub __slots__: ', Sub.__slots__)
print('a __slots__: ', a.__slots__)
print('Sub __dict__: ', Sub.__dict__)
print('a __dict__: ', a.__dict__)
运行结果如下:
#顺利继承到了Super的__slots__属性
Sub __slots__: ['name']
a __slots__: ['name']
#此时Python用了大量的黑暗魔法,这时我们看到Sub的__dict__中居然出现了__dict__属性,且值为特殊的对象,相当于Sub.__slots__=Super.__slots__+['__dict__'],从而实现如果在__slots__中出现的属性存在__slots__中,没有出现的存在Sub的实例的__dict__中。
Sub __dict__: {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Sub' objects>, '__weakref__': <attribute '__weakref__' of 'Sub' objects>, '__doc__': None, '__init__': <function Sub.__init__ at 0x7fc35f7036a8>}
#我们确实看到了age存在了子类的实例的__dict__中。
a __dict__: {'age': 22}
如果子类和父类都有__slots__...
class Super:
__slots__=['name','age']
class Sub(Super):
__slots__=['city']
print('Sub __slots__: ', Sub.__slots__)
print('Sub __dict__: ', Sub.__dict__)
运行结果如下:
#父类中的__slots__没有对子类产生影响
Sub __slots__: ['city']
#再次证明了上面的说法,如果一定需要父类的__slots__进行叠加,那么需要手动设置为__slots__=Super.__slots__ + ['city'],所以可以看出Python通过了大量的黑暗魔法,从而达到__slots__不具有常规的继承特性。
Sub __dict__: {'__slots__': ['city'], '__module__': '__main__', 'city': <member 'city' of 'Sub' objects>, '__doc__': None}
如果一个子类继承自一个没有__slots__的超类...
如果一个子类继承自一个没有__slots__的超类,那么超类的__dict__属性总是可以访问的,使得子类中的一个__slots__无意义。
留给你自己验证一下吧。
总结
__slots__用来设计成对实例的__dict__的限制,只有__dict__出现在__slots__中,实例才会有__dict__属性。
否则,只有出现在__slots__中的属性才可以被使用。- Python特意设计成
__slots__没有常规的继承特性,所以只有超类具有__slots__且其__dict__属性没有出现在其中,这时子类的__slots__才有意义,且子类的__slots__不继承父类的__slots__。
Python属性、方法和类管理系列之----__slots__属性的更多相关文章
- Python属性、方法和类管理系列之----属性初探
在学习dict的时候,肯定听过dict是Python中最重要的数据类型,但是不一定知道为什么.马上你就会明白原因了. Python中从模块.到函数.到类.到元类,其实主要管理方法就是靠一个一个的字典. ...
- Python属性、方法和类管理系列之----描述符类
什么是描述符类? 根据鸭子模型理论,只要具有__get__方法的类就是描述符类. 如果一个类中具有__get__和__set__两个方法,那么就是数据描述符,. 如果一个类中只有__get__方法,那 ...
- Python属性、方法和类管理系列之----元类
元类的介绍 请看位于下面网址的一篇文章,写的相当好. http://blog.jobbole.com/21351/ 实例补充 class Meta(type): def __new__(meta, c ...
- python 面向对象静态方法、类方法、属性方法、类的特殊成员方法
静态方法:只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性. 在类中方法定义前添加@staticmethod,该方法就与类中的其他(属性,方法)没有关系,不能通过实例化类调用方法使用 ...
- Python 属性方法、类方法、静态方法、 特殊属性__doc__ (内建属性)
总结:和类的关联性讲:属性方法>类方法>静态方法 属性方法@property:仅仅是调用方式不用+括号. 类方法@classmethod:访问不了累的属性变量,只可以访问类变量. 静态方法 ...
- python特殊方法定制类
#coding:utf-8class RoundFloat(object): def __init__(self,val): assert isinstance(val, float),"v ...
- ES6 属性方法简写一例:vue methods 属性定义方法
const o = { method() { return "Hello!"; } }; // 等同于 const o = { method: function() { retur ...
- Python类(六)-静态方法、类方法、属性方法
静态方法 通过@staticmethod来定义,静态方法在类中,但在静态方法里访问不了类和实例中的属性,但静态方法需要类来调用 # -*- coding:utf-8 -*- __author__ = ...
- python类属性和类方法(类的结构、实例属性、静态方法)
类属性和类方法 目标 类的结构 类属性和实例属性 类方法和静态方法 01. 类的结构 1.1 术语 —— 实例 使用面相对象开发,第 1 步 是设计 类 使用 类名() 创建对象,创建对象 的动作有两 ...
随机推荐
- 深入理解计算机系统第二版习题解答CSAPP 2.17
假设w=4,我们能给每个可能的十六进制数字赋予一个数值,假设用一个无符号或者补码表示.完成下表: x 无符号(B2U(x)) 补码(B2T(x)) 十六进制 二进制 0xE 1110 14 -2 0x ...
- I2C总线协议的总结介绍
在看天翔哥的视频之后,他强调要把I2C协议好好研究一下,那么就对一些基本的通信手段是十分有帮助的..那么就来了解一下I2C总线协议的一些知识吧. I2C(Inter-Integrated Circui ...
- 在安卓下使用python连接蓝牙串口模块(HC-06)
在安卓上安装Python: 请参考:https://github.com/kuri65536/python-for-android/blob/master/README.md下载程序文件需要访问 ht ...
- 目前电脑的硬件尺寸参数,计划弄个小一些的ATX机箱
显卡:讯景R9 370x 尺寸:234×115×39mm 主板:技嘉GA-970A-DS3P 尺寸: 30.5X21.5 cm
- JavaScript 零散知识点1 (正则表达式+定时器+hover)
1.clear:both清楚浮动影响//css中 2.正则表达式 search方法 :指明是否存在相应的匹配,如找到一个返回一个整数值,表明这个匹配距离字符串开始的偏移位置,如果没有找到匹配返回-1f ...
- MySQL 知识点
文件格式: frm.MYI.MYD 分别是 MyISAM 表的表结构\索引\数据文件 一个库在一个目录下 不过在 MySQL 4.0 以上版本中, 你可 ...
- Google Map JavaScript API V3 实例大全
Google Map JavaScript API V3 实例大全 基础知识 简单的例子 地理位置 语言 位置 坐标 简单的投影 事件 简单事件 关闭事件 多次添加事件 事件属性 控制 php禁用ui ...
- 读取tomcat下的文件夹路径
背景:测试的为了每次部署时清缓存,将temp文件夹也删了,导致系统中有些excel导出功能用不了. 解决:新建一个监听文件,在系统启动时,判断temp文件夹是否存在,不存在就新建. temp文件夹的作 ...
- Sytem 表空间很大
SYSTEM表空间使用率达到了99%, 经查出,是审计表AUD$占用绝大部分的空间. -- 占用表空间system对象大小排名 SELECT * MB FROM DBA_SEGMENTS WHERE ...
- IOS 高级开发 KVC(二)
前一篇博客最后介绍了KVC 再json 转模型时遇到一些问题.今天接着来介绍KVC 的其他用法.其实我们在一开始的时候就一直再强调命名的重要性.命名规范是KVC 存活的基础.如果没有这个条件支撑,那么 ...