侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Python中__slots__属性介绍与基本使用方法

Python  /  管理员 发布于 7年前   190

简介

在廖雪峰的python网站上,他是这么说的

python是动态语言,它允许程序在执行过程中动态绑定属性或者方法(使用MethodTpye)。

某个实例在执行过程中绑定的属性跟方法,仅在该实例中有效,其他同类实例是没有的。

可以通过给class绑定属性/方法,来给所有实例绑定属性/方法:

Student.name = ''Student.set_score = set_score

而如果使用__slots__,它仅允许动态绑定()里面有的属性

例如,下面这样会报错

class Student():__slots__ = ('name', 'age')S1 = Student()S1.name = 'Jack' # ok!S1.score = 123 # error!

但是我觉得很奇怪,仅有这一个作用吗?于是我再查了其他资料,发现这个函数可以很可观地节约内存,下面来一起看看详细的介绍吧。

__slots__允许我们声明并限定类成员,并拒绝类创建__dict__和__weakref__属性以节约内存空间。

Python是动态语言,对于普通的类,可以为类实例赋值任何属性,这些属性会存储在__dict__中:

>>> class Student(object):... pass... >>> Abey = Student()>>> Abey.name = 'Abey'>>> Abey.__dict__{'name': 'Abey'}

这样的特性带来两个问题:

  • 数据通过字典(Hash)存储所占用的空间较大
  • 如何禁止随意生成类属性

当然,__slots__就能解决这两个问题。通过__slots__属性限定类属性的创建:

>>> class Student(object):... __slots__ = ('name', 'age')... >>> Abey = Student()>>> Abey.name = 'Abey'>>> Abey.gender = 'Female'Traceback (most recent call last): File "<input>", line 1, in <module>AttributeError: 'Student' object has no attribute 'gender'>>> Abey.__dict__Traceback (most recent call last): File "<input>", line 1, in <module>AttributeError: 'Student' object has no attribute '__dict__'

可以看到,在定义了__slots__变量后,Student类实例已经不能随意创建不在__slots__定义内的属性gender,同时实例中也不再有__dict__结构。

用法

继承树

__slots__在继承中有两种表现:

  • 子类未声明__slots__时,不继承父类的__slots__,即此时子类实例可以随意赋值属性
  • 子类声明__slots__时,继承父类的__slots__,即此时子类的__slots__为其自身+父类的__slots__

以下面的父类为例:

>>> class Student(object):... __slots__ = ('name', 'age')... 

创建一个子类不声明__slots__,该类实例可以创建父类__slots__限定之外的属性gender:

>>> class SubStudent(Student):... pass... >>> Bob = SubStudent()>>> Bob.gender = 'Male'>>> Bob.__dict__{'gender': 'Male'}

而创建一个声明__slots__的子类,该类属性则只能创建父类__slots__+自身__slots__限定的属性:

>>> class SubStudent2(Student):... __slots__ = 'gender'... >>> Cathy = SubStudent2()>>> Cathy.gender = 'Female'>>> Cathy.name = 'Cathy'>>> Cathy.teacher = 'Mrs. Wang'Traceback (most recent call last): File "<input>", line 1, in <module>AttributeError: 'SubStudent2' object has no attribute 'teacher'

注意:子类的__slots__本身已经继承自父类,无需重复声明父类已声明的属性。例如上例,重复声明会多占用内存空间:

>>> class SubStudent3(Student):... __slots__ = ('name', 'age', 'gender')... >>> from sys import getsizeof>>> getsizeof(Student()), getsizeof(SubStudent2()), getsizeof(SubStudent3())(56, 64, 80)

性能对比

我们为什么要使用__slots__呢?

更快速地赋值属性

参考Stack Overflow回答中给出的数据:

import timeitclass Foo(object): __slots__ = 'foo',class Bar(object): passslotted = Foo()not_slotted = Bar()def get_set_delete_fn(obj): def get_set_delete(): obj.foo = 'foo' obj.foo del obj.foo return get_set_delete

得到测试结果为:

>>> min(timeit.repeat(get_set_delete_fn(slotted)))
0.2846834529991611
>>> min(timeit.repeat(get_set_delete_fn(not_slotted)))
0.3664822799983085

可以看到,在相同的环境(Ubuntu)下,slots为Python3.5带来了接近30%的赋值速度提升:

节约内存空间

>>> 0.3664822799983085 / 0.28468345299916111.2873325658284342

由于不使用__dict__存储对象的属性,__slots__在一些场景下能够节约极大的内存空间。具体数据可以查看参考中的回答链接,不赘述。

参考

[1] Usage of __slots__? ,  Aaron Hall, Stack Overflow

推荐阅读

[1] Data model , Python Document

[2] python __slots__ 使你的代码更加节省内存 , david_bj, 51CTO

[3] 使用__slots__ , 廖雪峰

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家的支持。


  • 上一条:
    python使用__slots__让你的代码更加节省内存
    下一条:
    python使用xlrd和xlwt读写Excel文件的实例代码
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客