Python __slots__的使用方法_python

来源:脚本之家  责任编辑:小易  

学Python应先从2113Python开发基础部分入手,如学习Python语言5261介绍、环境安4102装、 Python基本语法、基本数据1653类型、 二进制运算、弯码枣流程控制、 字符编码、文件处理、 数据类型、用户认证、函数、 三级菜单程序、购物车程序开发、 员工信息表开发、内置方法、 递归、迭代器、装饰器、 模块的跨目录导入、 b加密\re正则\logging日志模块、 常用标准库学习、 软件开发规范学习、模猛 计算器程序、 ATM程序开发等埋拆,学完这些基本算是入门了,术语表argument 实参attribute 属性2113base class 基本类block 块character 字符5261class 类comment 注释complex number 复数derived class 导出类dictionary 字典4102escape sequence 转义符exception 异常expression 表达式field 域float 浮点数function 函数identifier 标识1653符indentation 缩进indexing 索引instance 实例integer 整数list 列表list comprehension 列表综合literal constant 字面意义上的常量logical line 逻辑行long integer 长整数method 方法module 模块namespace 名称空间object 对象operand 操作数operator 运算符parameter 形参pickle 储存器physical line 物理行sequence 序列shebang line 组织行slicing 切片statement 语句string 字符串subclass 子类superclass 超类tuple 元组type 类型variable 变量,Python解释器Python文本编辑器Python代码2113运行助手输入5261和输出Python基础数据类型和变量字符4102串和编码使用1653list和tuple条件判断循环使用dict和set函数调用函数定义函数函数的参数递归函数高级特性切片迭代列表生成式生成器迭代器函数式编程高阶函数map/reducefiltersorted返回函数匿名函数装饰器偏函数模块使用模块安装第三方模块面向对象编程类和实例访问限制继承和多态获取对象信息实例属性和类属性面向对象高级编程使用__slots__使用@property多重继承定制类使用枚举类使用元类错误、调试和测试错误处理调试单元测试文档测试IO编程文件读写StringIO和BytesIO操作文件和目录序列化进程和线程多进程多线程ThreadLocal进程 vs. 线程分布式进程正则表达式常用内建模块datetimecollectionsbase64structhashlibhmacitertoolscontextliburllibXMLHTMLParser常用第三方模块Pillowrequestschardetpsutilvirtualenv图形界面网络编程TCP/IP简介TCP编程UDP编程电子邮件SMTP发送邮件POP3收取邮件访问数据库使用SQLite使用MySQL使用SQLAlchemyWeb开发HTTP协议简介HTML简介WSGI接口使用Web框架使用模板异步IO协程asyncioasync/awaitaiohttp本回答被网友采纳www.zgxue.com防采集请勿采集本网。

准备

正常情况下,创建class的实例后,可以给该实例绑定任何属性和方法,这就是动态语言的灵活性。首先定义一个class

首先: Python 2.x中默认都是经典类,只有显式继承了object才是新式类 Python 3.x中默认都是新式类,不必显式的继承object 其次: ------新式类对象可以直接通过__class__属性获取自身类型:type ------继承搜索的顺序发生了改变,经典类多继承属

class A(object): pass

然后创建一个实例,并给实例添加属性和方法。

a = A()print a.__dict__ #{}A.name = 'xiaoming' #动态的给实例绑定属性,其实例属性会保存到实例的__dict__中print a.__dict__ #{'name': 'xiaoming'}f = lambda :100a.fun = f print a.__dict__ #{'fun': <function <lambda> at>, 'name': 'xiaoming'}

此时的name属性和fun()方法只有实例a能使用,类A的其他实例不能使用,如果想让类A的所有实例都能使用,我们需要给类A绑定方法

print A.__dict__ #...f = lambda :100A.fun = f print A.__dict__ #... + 'fun': <function <lambda> at 0x0000000003582978>

此时,类A的所有实例就能使用方法fun()了。

​ 通常情况下,上面的fun()方法应该定义在class中,但动态绑定允许在程序运行的过程中动态的给class增加功能,这在静态语言中很难实现,这也是动态语言的优点。

__slots__

​ 如果在一个类中定义了__slots__属性,那么这个类的实例将不会拥有__dict__属性,没有__dict__的实例也就不能添加实例属性了。简单来说,__slots__的作用就是阻止类在实例化时为实例分配__dict__属性,限制该实例能添加的属性。

作用

​ 通常情况下实例使用__dict__来存储自己的属性,它允许实例动态地添加或删除属性。然而,对一些在编译期就已经知道有什么变量的类或者不允许动态添加变量的类来说,它们并不需要动态地添加变量。如果想要限制实例属性,不想让它动态添加属性怎么办?比如我们只允许对A的实例添加name和age属性。

​ 为了达到上述目的,Python允许在定义class的时候,定义一个__slots__变量,来限制该class的实例能添加的属性。

class A(object): __slots__ = ('age','name')a = A()a.name = 'xiaoming'a.age = 10a.id = 123456 #error AttributeError: 'A' object has no attribute 'id'

由于id不在__slots__中,所以实例不能添加id属性。任何试图给实例添加一个其名不在__slots__中的属性都将触发AttributeError异常。

实现原理

__slots__中的变量是类属性,类型为数据描述符

#!/usr/bin/python# -*- coding: utf-8 -*-class Foo(object): __slots__ = ('age','name') def __init__(self,age = 0): self.age = ages = Foo.__dict__['age']print s #<member 'age' of 'Foo' objects>print type(s) #<type 'member_descriptor'>'''证明为数据描述符'''print '__get__' in dir(s) #Trueprint '__set__' in dir(s) #True

__slots__中的变量虽然是类属性,但是不同实例之间互不影响。因为描述符方法的一个参数为实例,建立一个实例和值的映射还是很简单的。如果不懂,建议看描述符

f1 = Foo(1)f2 = Foo(2)print f1.age,f2.age #1,2print Foo.__dict__['age'].__get__(f1) #1print Foo.__dict__['age'].__get__(f2) #2

__slots__的好处

如果类没有定义__slots__ ,该类的实例会有__dict__属性,通过__dict__可修改,删除,增加实例属性。

如果类定义了__slots__,该类的实例不会有__dict__属性。实例中的__dict__属性是非常耗内存的,当创建上百万个实例的时候,所有实例的__dict__会占用一块很大的内存。没有了__dict__的实例也就不能动态添加属性,只需分配固定的空间来存储已知的属性。因此使用__slots__的类能节省一部分内存开销。

对于不需要动态添加属性的类来说,应使用__slots__。

注意:不用过早的使用这个方法,它不利于代码维护,当实例很多(上千万)时,这种优化才有明显的效果。在实际使用中,__slots__从未被当作一种安全的特性来使用,它是对内存和执行速度的一种性能优化。使用__slots__的类的实例不再使用字典来存储实例属性,而是使用基于数组的一种更加紧凑的数据结构,所以当实例很多时,使用__slots__可以显著减少内存占用和执行时间。

class A(object): passclass B(object): __slots__ = ('age','name')a = A()b = B()

没有__slots__的类和实例

print a.__dict__ #{}print A.__dict__ '''{'__dict__': <attribute '__dict__' of 'A' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}'''

有__slots__的类和实例

print b.__dict__ #AttributeError: 'B' object has no attribute '__dict__'print B.__dict__'''{'age': <member 'age' of 'B' objects>, '__module__': '__main__', '__doc__': None, '__slots__': ('age', 'name'), 'name': <member 'name' of 'B' objects>}'''

使用定义__slots__的类的注意事项

class Foo(object): __slots__ = ('age','name')

1.__slots__仅对当前类起作用,对子类是不起作用的,除非在子类中也定义__slots__,这样,子类允许定义的属性就是自身的__slots__加上父类的__slots__。

class F1(Foo): passclass F2(Foo): __slots__ = ()f1,f2 = F1(),F2()f1.a = 1f2.a = 1 #AttributeError: 'F2' object has no attribute 'a'f2.age = 1

2.如果实例未给__slots__中的变量赋值,该实例不能使用__slots__中的变量。

f = Foo()print f.age #AttributeError: agef.age = 1print f.age #1

3.实例将不再拥有__dict__,但是类还是拥有__dict__属性的,所以还是可以给类增加类属性的;

f = Foo()Foo.xx = 1print f.xx #1

4.定义了__slots__后,如果__slots__中的变量为类变量,该变量对于该类的实例来说是只读的。如果想修改的话,可以通过类来修改。

class Foo(object): __slots__ = ('age','name') age = 10 def __init__(self): self.name = 'xiaoming'f = Foo()print f.name #'xiaoming'print f.age #10f.name = 'xiaohong' #f.age = 12 #AttributeError: 'Foo' object attribute 'age' is read-onlyFoo.age = 12 #正确print f.name #'xiaohong'print f.age #12#del f.age #AttributeError: 'Foo' object attribute 'age' is read-only#del f.name 调用的是描述符方法__delete__,应该是将描述符中存储的实例与值的映射删除了del f.name #实例属性的删除还是可以的,但是删除的并不是类字典中的name属性print f.name #AttributeError: namedel Foo.age #通过类来删除类属性还是可以的,不过这样会影响该类的所有实例print f.age #AttributeError: 'Foo' object has no attribute 'age'

原因不知道…有知道的大神求指导…

参考网址

1.http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0013868200605560b1bd3c660bf494282ede59fee17e781000

2.http://www.jianshu.com/p/ef1797577f71

3.http://www.jianshu.com/p/82ce2151d73b

4.http://blog.csdn.net/lis_12/article/details/53453665

到此这篇关于Python __slots__的使用方法的文章就介绍到这了,更多相关Python __slots__内容请搜索真格学网以前的文章或继续浏览下面的相关文章希望大家以后多多支持真格学网! 您可能感兴趣的文章:Python类中的魔法方法之 __slots__原理解析python使用__slots__让你的代码更加节省内存Python中__slots__属性介绍与基本使用方法Python中的__slots__示例详解python中__slots__用法实例在Python中使用__slots__方法的详细教程用Python中的__slots__缓存资源以节省内存开销的方法python中的__slots__使用示例Python中的__SLOTS__属性使用示例

>>> class ws(object):...   __slots__ = 'a', 'b'...   def __init__(self, a=23, b=45): self.a, self.b = a, b... >>> x = ws()>>> import pickle>>> pickle.dumps(x, -1)'\x80\x02c__main__\nws\nq\x00)\x81q\x01N}q\x02(U\x01aq\x03K\x17U\x01bq\x04K-u\x86q\x05b.'>>> pickle.dumps(x)Traceback (most recent call last):    [[snip]]  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/copy_reg.py", line 77, in _reduce_ex    raise TypeError("a class that defines __slots__ without "TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled>>>pickle.dumps的时2113候使用-1协议。如果解5261决了您的问题请采纳!4102如果未解1653决请继续追问内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • python3 log10()函数简单用法
  • python 追踪except信息方式
  • python pandas找到缺失值的位置方法
  • python将数组n等分的实例
  • 对python 简单串口收发gui界面的实例详解
  • python中字符串数组逆序排列方法总结
  • python3.5基础之numpy模块的使用图文与实例详解
  • 使用python paramiko模块利用多线程实现ssh并发执行操作
  • 对pytorch的函数中的group参数的作用介绍
  • python爬虫_实现校园网自动重连脚本的教程
  • Python __slots__类如何使用cpickle进行序列化和反...
  • Python的基本术语有哪些
  • Python类继承自object为什么要super自己的方法
  • Python中dict为什么比list浪费内存?求大神,感激...
  • Python新式类和经典类的区别
  • Python新式类和经典类的区别
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全vbsdos/bathtahtcpythonperl游戏相关vba远程脚本coldfusionruby专题autoitseraphzonepowershelllinux shellluagolangerlang其它首页python数据描述符描述符python类中的魔法方法之 __slots__原理解析python使用__slots__让你的代码更加节省内存python中__slots__属性介绍与基本使用方法python中的__slots__示例详解python中__slots__用法实例在python中使用__slots__方法的详细教程用python中的__slots__缓存资源以节省内存开销的方法python中的__slots__使用示例python中的__slots__属性使用示例python3 log10()函数简单用法python 追踪except信息方式python pandas找到缺失值的位置方法python将数组n等分的实例对python 简单串口收发gui界面的实例详解python中字符串数组逆序排列方法总结python3.5基础之numpy模块的使用图文与实例详解使用python paramiko模块利用多线程实现ssh并发执行操作对pytorch的函数中的group参数的作用介绍python爬虫_实现校园网自动重连脚本的教程python入门教程 超详细1小时学会pycharm 2020最新永久激活码(附python 列表(list)操作方法详解python 元组(tuple)操作详解python 字典(dictionary)操作详解pycharm 使用心得(一)安装和首python strip()函数 介绍python 中文乱码问题深入分析python中使用xlrd、xlwt操作excepycharm 2020年最新激活码(亲测pytorch中tensor的数据统计示例django框架静态文件处理、中间件、上传文python pip配置国内源的方法在python中利用pycharm自定义代码块教程(用virtualenv建立多个python独立虚拟开发python读写/追加excel文件demo分享python 遍历子文件和所有子文件夹的代码实详解python并发获取snmp信息及性能测试numpy.array 操作使用简单总结python使用turtle库绘制奥运五环
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved