#!/usr/bin/env python3
#-*- coding:utf-8 -*-
#slots用法解析:
#默认情况下Python用一个字典来保存一个对象的实例属性,它允许我们在运行时去设置任意的新属性
#__slots__允许我们声明并限定类成员,并拒绝类创建__dict__和__weakref__属性以节约内存空间。
#子类未声明__slots__时,不继承父类的__slots__,即此时子类实例可以随意赋值属性
#子类声明__slots__时,继承父类的__slots__,即此时子类的__slots__为其自身+父类的__slots__
#如果父类存在__dict__属性,则其子类将继承__dict__;此时,即使该子类包含了__slots__属性,该子类的实例依然可以任意添加变量
#创建一个声明__slots__的子类,该类属性则只能创建父类__slots__+自身__slots__限定的属性
#python3中,不允许在类内定义跟slots里面的属性同名;在slots外面定义的属性是只读的; 如果T2继承自T(没有定义slots的父类),则slots失去了原有的含义
from memory_profiler import profile
class T(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "[%d][%d-%d]"%(id(self), self.x, self.y)
class T1(object):
__slots__ = ("x", "y")
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "[%d][%d-%d]"%(id(self), self.x, self.y)
class T2(T1):
__slots__ = ("x", "y", "z")
s = 20
#@profile
def main():
#l = [T(x, x) for x in range(100000)]
#l1 = [T1(x, x) for x in range(100000)]
#l2 = [T2(x, x) for x in range(100000)]
"""
python -m memory_profiler ~/Desktop/test_slots.py
Filename: /Users/nnn/Desktop/test_slots.py
Line # Mem usage Increment Line Contents
================================================
21 25.0 MiB 25.0 MiB @profile
22 def main():
23 67.9 MiB 3.1 MiB l = [T(x, x) for x in range(100000)]
24 78.8 MiB 2.3 MiB l1 = [T1(x, x) for x in range(100000)]
25 117.6 MiB 2.3 MiB l2 = [T2(x, x) for x in range(100000)]
"""
t = T1(1,2)
print(t.y)
t.z = 30
print(t.z)
print(dir(t))
import pdb;pdb.set_trace()
if __name__=='__main__':
main()