本文相关描述主要是个人的认知和见解,如有不当之处,还望各位大佬指正。
个人其他博客地址:
简书:https://www.jianshu.com/u/d6960089b087
掘金:https://juejin.cn/user/2963939079225608
小钟同学 | 文 【原创】| QQ:308711822
1 前言
我们的知道python动态性让我们的可以为所欲为。甚至是运行时可以动态的新增属性。但是这种任意性有时候也是需要要付出代价的。那就是我们的对象可能需要新增更多的内存的开销。
2 关于类中的__dict__属性
python类中有内置的属性__dict__,它是一个python类中默认用来存储一个对象的实例属性的一个字典。
但是不是所有的类都有这个__dict__属性, 如:常见的容器对象
dd = []
dd.__dict__
此时的结果是:
Traceback (most recent call last):
File "D:/code/python/local_python/AntFlask/ceshi2.py", line 5, in <module>
dd.__dict__
AttributeError: 'list' object has no attribute '__dict__'
而自定义的类通常默认的是会有__dict__属性:
class Ape:
# 定义__call__方法
def __init__(self,name):
self.name = name
print(Ape.__dict__)
a = Ape('妈妈')
print(a.__dict__)
输出的结果为:
{'__module__': '__main__', '__init__': <function Ape.__init__ at 0x000001C58E4B3D08>, '__dict__': <attribute '__dict__' of 'Ape' objects>, '__weakref__': <attribute '__weakref__' of 'Ape' objects>, '__doc__': None}
{'name': '妈妈'}
关于继承的一个示例:
class Ape:
# 定义__call__方法
def __init__(self, name):
self.name = name
print(Ape.__dict__)
a = Ape('妈妈')
print(a.__dict__)
class KAS(Ape):
kkkk = '啊啊啊'
print(KAS.__dict__)
a = KAS('新的世界')
print(a.__dict__)
输出:
{'__module__': '__main__', '__init__': <function Ape.__init__ at 0x000001AB1B633D08>, '__dict__': <attribute '__dict__' of 'Ape' objects>, '__weakref__': <attribute '__weakref__' of 'Ape' objects>, '__doc__': None}
{'name': '妈妈'}
{'__module__': '__main__', 'kkkk': '啊啊啊', '__doc__': None}
{'name': '新的世界'}
关于__dict__属性的总结:
python内置的数据类型没有__dict__属性
对象有自己的属性,保存的是对象自身的属性信息
每个类也有自己的__dict__属性
父类的__dict__ 并不会影响子类的__dict__
子类和父类的实例对象共享同一个__dict__
3 __slots__限制类实例绑定的属性,不要额外的分配太多其他无关的属性
__slots__可以用于限制我们的示例属性的绑定,意思就是只限制固定的分配几个属性值,其他不需要分配。
作用:
限制类实例动态添加属性和方法 避免用户频繁的给实例对象动态地添加属性或方法
注意点:
slots 只能限制【实例对象】动态添加属性和方法 slots 不能限制 【类】 动态添加属性和方法
如下示例:
没有限制的情况下
class Ape:
# 定义__call__方法
def __init__(self, name):
self.name = name
from memory_profiler import profile
@profile(precision=4)
def my_func():
return [Ape("as" + str(i)) for i in range(1000000)]
my_func()
查看输出:
Filename: D:/code/python/local_python/AntFlask/ceshi2.py
Line # Mem usage Increment Occurences Line Contents
============================================================
12 18.8438 MiB 18.8438 MiB 1 @profile(precision=4)
13 def my_func():
14 251.7539 MiB -775.8594 MiB 1000003 return [Ape("as" + str(i)) for i in range(1000000)]
加了限制之后:
class Ape:
__slots__ = ['name']
def __init__(self, name):
self.name = name
from memory_profiler import profile
@profile(precision=4)
def my_func():
return [Ape("as" + str(i)) for i in range(1000000)]
my_func()
输出结果:
Filename: D:/code/python/local_python/AntFlask/ceshi2.py
Line # Mem usage Increment Occurences Line Contents
============================================================
12 18.9258 MiB 18.9258 MiB 1 @profile(precision=4)
13 def my_func():
14 134.9531 MiB -3311.0977 MiB 1000003 return [Ape("as" + str(i)) for i in range(1000000)]
输出的内存结果的说明:参数说明:
line 已分析的代码的行号 Mem usage:表示执行该行后Python解释器的内存使用情况 Increment:表示当前行的内存相对于上一行的差异,即自己本身增长了多少,如果减少了则不显示.
End
纯属个人实践中相关经验阐述总结,如有纰漏,还希望大佬们多多提点!小钟同学 | 文 【原创】| QQ:308711822
文章转载自小儿来一壶枸杞酒泡茶,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




