如何派生内置不可变类型并修改其实例化行为

# 类与对象深度问题与解决技巧
# 如何派生内置不可变类型并修改其实例化行为
# 我们想定义一种新类型的元组对于传入的可迭代对象 我们只保留其中int类型值大于0的元素
# 例如:
# IntTuple([2,-2,'jr',['x','y'],4])    #=> (2,4)

# 如何继承内置tuple实现IntTuple

# 2 如何为创建大量实例节省内存
# 在游戏中定义了玩家类player,每有一个在线玩家,在服务器内则有一个player的实例,
# 当在线人数很多时,将产生大量实例(百万级)
# 如何降低大量实例的内存开销

class IntTuple(tuple):
    def __init__(self,iterable):
        for i in iterable:
            if isinstance(i,int) and i > 0:
                super().__init__(i)
    #    print(self)


int_t =IntTuple ([2,-2,'jr',['x','y'],4])

print(int_t)   # 2,4

# self 对象到底是谁创建的?

class A(object):
    def __new__(cls, *args, **kwargs):
        print('A.__new__',cls,args)
        return object.__new__(cls)
        # return super().__new__(cls)     # 使用super()也可以但最好用object


    def __init__(self,*args):
        print('A.__init__')


a = A(1,2)
a = A.__new__(A,1,2)
A.__init__(a,1,2)


class IntTuple(tuple):
    def __new__(cls,iterable):
        # for i in iterable:
        #     if isinstance(i,int) and i > 0:
        #         super().__init__(i)
        # 生成器
        # f = (i for i in iterable if isinstance(i,int) and i > 0)
        f = [i for i in iterable if isinstance(i,int) and i > 0]
        return super().__new__(cls,f)

int_t =IntTuple([2,-2,'jr',['x','y'],4])

print(int_t)   # 2,4

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

# 2 如何为创建大量实例节省内存
# 在游戏中定义了玩家类player,每有一个在线玩家,在服务器内则有一个player的实例,
# 当在线人数很多时,将产生大量实例(百万级)
# 如何降低大量实例的内存开销

import sys       # 导入系统模块 查看占内存多少
import tracemalloc   # 统计内存 跟踪内存使用


class Player1(object):
    def __init__(self,uid,name,status=0,level=1):
        self.uid = uid
        self.name = name
        self.status = status
        self.level =level

class Player2(object):
    __slots__ = ('uid','name','status','level')
    def __init__(self,uid,name,status=0,level=1):
        self.uid = uid
        self.name = name
        self.status = status
        self.level =level


# p1 = Player1('0001','ellen')
# p2 = Player2('0002','ellen')

# print(dir(p1))       # 查看p1属性
# print(len(dir(p1)))     # 查看属性长度 30
# print(dir(p2))          # 查看p2属性
# print(le(dir(p2)))     # 29

# __weakref__  # 弱引用
# __dict__     # 动态绑定属性

# print(set(dir(p1))-set(dir(p2)))  -->

# p1.x = 6       # 动态绑定添加属性 及其浪费内存
# p1.__dict__['y']=7   # 动态绑定添加属性
# print(p1.__dict__)

# print(p2.name)    #  p2添加__slots__后取值可以,
# p2.y = 7      #   动态添加属性会报错
 
 # 导入系统模块 查看对象所占内存__dict__占内存最大
# print(sys.getsizeof(p1.__dict__))    --> 112
# print(sys.getsizeof(p1.name))       --> 54
# print(sys.getsizeof(p1.uid))     -- >  53

导入 tracemalloc 统计内存 跟踪内存使用
tracemalloc.start()    # 开启
p1 = [Player1(1,2,3) for _ in range(100000)]   # size=16.8 MiB    _ in 不需要循环里的值 不想取变量名字用下划线代替。
p2 = [Player2(1,2,3) for _ in range(100000)]    # size=7837 KiB
end = tracemalloc.take_snapshot()
# top = end.statistics('lineno')
top = end.statistics('filename')

for stat in top[:10]:
    print(stat)

总结:
解决方案:
定义类的__slots__属性,声明实例有哪些属性(关闭动态绑定)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值