微信扫一扫打赏支持

python中的__slots__使用及其定义

python中的__slots__使用及其定义

打赏

 

一、总结

一句话总结:

如果要限制在运行的时候给类添加属性,Python允许在定义class的时候,定义一个特殊的_slots__变量,来限制该class实例能添加的属性。
class Player2(object):
    __slots__ = ['uid', 'name', 'stat', 'level', 'sex']

    def __init__(self, uid, name, stat=0, level=1):
        self.uid = uid
        self.name = name
        self.stat = stat
        self.level = level

 

 

 

二、python中的__slots__使用极其定义(转)

转自或参考:python中的__slots__使用极其定义(转) - 就是想学习 - 博客园
https://www.cnblogs.com/sidianok/p/12044151.html

如果我们想要限制实例的属性,Python允许在定义class的时候,定义一个特殊的slots变量,来限制该class实例能添加的属性。
使用slots要注意,slots定义的属性仅对当前类实例起作用,对继承的子类是不起作用的
除非在子类中也定义slots,这样,子类实例允许定义的属性就是自身的slots加上父类的slots

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
# coding:utf-8
class Player(object):
    def __init__(self, uid, name, stat=0, level=1):
        self.uid = uid
        self.name = name
        self.stat = stat
        self.level = level
 
 
class Player2(object):
    __slots__ = ['uid', 'name', 'stat', 'level', 'sex']
 
    def __init__(self, uid, name, stat=0, level=1):
        self.uid = uid
        self.name = name
        self.stat = stat
        self.level = level
 
 
class Player3(Player2):
    def __init__(self, uid, name):
        super(Player3, self).__init__(uid, name)
 
 
class Player4(Player2):
    __slots__ = ['age']
 
    def __init__(self, uid, name):
        super(Player4, self).__init__(uid, name)

 

slots应用实例

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

问题:某游戏中,定义了玩家类Player(uid, name, status...),每有一个在线玩家,在服务器程序内则有一个Player的实例,当在线人数很多时,将产生大量实例(如百万级)
解决方案:定义类的slots属性,它时用来声明实例属性名字的列表。

交互模式下看到p1和p2的属性,p1比p2使用的内存多,为什么呢,通过对比发现,属性多了__dict____weakref__

 
底层的理解。
在__slots__的类下,实例创建不会带有__dict__,所以无法新建属性,只能读取类的属性。
__slots__中的各个字符串会产生对应的描述符,实例在对限制的属性进行操作时,其实是在对类属性中定义的描述符进行操作。
所以实例没有办法真正的删除该属性。
 
Python学习笔记书中的解释:对于有__slots__设置的类型。解释器在创建类型对象时,直接将指定成员包装成描述符后静态分配到类型对象尾部。
实例字段也不能通过__dict__存储,而是改为直接分配引用内存。这样一来,只能替换引用内容,无法改变成员名字,更无法分配新的成员空间。
 
成员后续操作均由描述符完成。可间接修改或删除字段内容,但无法删除描述符本身。(类属性,实例无法删除)
 
注意这也Python处理大量对象的时候,一种优化的方案。可以很好的节省内存。
 
 
posted @   范仁义  阅读(426)  评论(0编辑  收藏  举报
努力加载评论中...
侧边栏

打赏

点击右上角即可分享
微信分享提示