python3 如何为创建大量实例节省内存?__slots__

案例:

  某网络游戏中,定义了玩家类Player(id, name, status,....),每有一个在线玩家,在服务器程序内有一个Player的实例,当在线人数很多时,将产生大量实例(百万级别)

  需求:

如何降低这些大量实例的内存开销?
如何做?

首先要明白,python中的类可以动态的添加属性,实则在内存中有个__dict__方法维护了这种动态添加属性,它占有内存,把它关掉,不就达到省内存要求了?

Python
# -*- coding: utf-8 -*- """ @author:songhao @file: c3.py @time: 2017/12/08 """ import sys class Payer: def __init__(self, id, name, status=1, level=0): self.id = id self.name = name self.status = status self.level = level class Payer2: __<span class="wp_keywordlink_affiliate"><a href="https://www.168seo.cn/tag/slots" title="View all posts in slots" target="_blank">slots</a></span>__ = ["id", "name", "status", "level"] def __init__(self, id, name, status=1, level=0): self.id = id self.name = name self.status = status self.level = level def main(): pass if __name__ == '__main__': p = Payer(1, "songhao") print(sys.getsizeof(p)) print(p.__dict__) # 为p实例添加 变量 p.x = "xsonghao" print(p.x) print(p.__dict__) # 删除属性 del p.x print(p.__dict__) # 打印__dict__占用的内存空间 print(sys.getsizeof(p.__dict__)) print("分割符__<span class="wp_keywordlink_affiliate"><a href="https://www.168seo.cn/tag/slots" title="View all posts in slots" target="_blank">slots</a></span>__".center(50, "*")) p2 = Payer2(1, "songhao") # print(p2.__dict__) """ Traceback (most recent call last): File "/Users/songhao/Desktop/Python3 入门和进阶/Python file/d11/c3.py", line 46, in <module> print(p2.__dict__) AttributeError: 'Payer2' object has no attribute '__dict__' """ print(sys.getsizeof(p2)) #p2.x = "xsonghao" """ {'id': 1, 'name': 'songhao', 'status': 1, 'level': 0, 'x': 'xsonghao'} p2.x = "xsonghao" {'id': 1, 'name': 'songhao', 'status': 1, 'level': 0} AttributeError: 'Payer2' object has no attribute 'x' """
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# -*- coding: utf-8 -*-
"""
@author:songhao
@file: c3.py
@time: 2017/12/08
"""
import sys
 
 
class Payer :
     def __init__ ( self , id , name , status = 1 , level = 0 ) :
         self . id = id
         self . name = name
         self . status = status
         self . level = level
 
 
class Payer2 :
     __slots__ = [ "id" , "name" , "status" , "level" ]
 
     def __init__ ( self , id , name , status = 1 , level = 0 ) :
         self . id = id
         self . name = name
         self . status = status
         self . level = level
 
 
def main ( ) :
     pass
 
 
if __name__ == '__main__' :
     p = Payer ( 1 , "songhao" )
     print ( sys . getsizeof ( p ) )
     print ( p . __dict__ )
     # 为p实例添加 变量
     p . x = "xsonghao"
     print ( p . x )
     print ( p . __dict__ )
     # 删除属性
     del p . x
     print ( p . __dict__ )
     # 打印__dict__占用的内存空间
     print ( sys . getsizeof ( p . __dict__ ) )
     print ( "分割符__slots__" . center ( 50 , "*" ) )
     p2 = Payer2 ( 1 , "songhao" )
     # print(p2.__dict__)
     """
    Traceback (most recent call last):
    File "/Users/songhao/Desktop/Python3 入门和进阶/Python file/d11/c3.py", line 46, in <module>
    print(p2.__dict__)
    AttributeError: 'Payer2' object has no attribute '__dict__'
    """
     print ( sys . getsizeof ( p2 ) )
     #p2.x = "xsonghao"
     """
    {'id': 1, 'name': 'songhao', 'status': 1, 'level': 0, 'x': 'xsonghao'}
    p2.x = "xsonghao"
    {'id': 1, 'name': 'songhao', 'status': 1, 'level': 0}
    AttributeError: 'Payer2' object has no attribute 'x'
    """

输出:

当你定义 __slots__ 后,Python就会为实例使用一种更加紧凑的内部表示。 实例通过一个很小的固定大小的数组来构建,而不是为每个实例定义一个字典,这跟元组或列表很类似。 在 __slots__ 中列出的属性名在内部被映射到这个数组的指定小标上。 使用slots一个不好的地方就是我们不能再给实例添加新的属性了,只能使用在 __slots__ 中定义的那些属性名。




  • zeropython 微信公众号 5868037 QQ号 5868037@qq.com QQ邮箱
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值