Python中slots的使用

默认情况下每个类都会有一个dict,这个dict维护了实例的所有属性,每个实例都有一个dict,并且通过__dict__访问。通过如下的例子来说明这个dict的使用。

class Test(object):
	x=9   #类变量
	
	def __init__(self):
		pass

t1=Test()
t2=Test()
t1.y=8     #给实例绑定一个属性
t2.x=5
print(t1.__dict__)
print(t2.__dict__)     

运行结果为:

可以看到的是,分别为t1和t2两个实例绑定了y和x属性,通过__dict__访问可以发现每个实例都有一个dict,互不相关。而且它并不存储类的属性。

然而在某些情况下,我们运行前就知道了某个类需要的属性时,这个dict就有点浪费内存,特别是当需要创建大量的实例时,内存浪费更加明显。而在新式类中,我们可以借助__slots__解决这个问题。

__slots__中我们限制了能够添加的属性,并为每个空间恰好预留足够的空间来保存变量,如此一来,python也不再使用dict。

class Test(object):
	__slots__=('x')
	def __init__(self):
		pass
	
t=Test()
t.x=9
print(t.x)
#t.y=0   #显示没有y这个属性,除了__slots__内的其他都不能绑定
#print(t.y)    
print(t.__dict__) #显示已无__dict__属性

在上面的例子中,我们通过__slots__限制只能添加x属性。当试图绑定属性y时不能成功。事实上,除了slots内的声明的属性其他的都不能进行绑定。而且此时输出dict也被告知不存在。

对于其他的类变量,被设置为readonly。

class Test(object):
	__slots__=('x')
	y=9
	def __init__(self):
		pass
	
t=Test()
t.y=0	
print(t.y)

运行结果为:

Python是一门动态语言,除了在运行过程中修改实例的属性之外,它还能增删方法。在此我们就不详说增删方法的使用。我们再通过一个对比的例子来加强对slots的用法的理解。

class test_slots(object):
	__slots__=('x')
	def __init__(self):
		pass
	
class test(object):
	def __init__(self):
		pass

t_s=test_slots()
t=test()
#print(dir(test_slots)) #类结构中包含__slots__,x,y
#print(dir(test))       #类结构包含__dict__
#print(dir(t_s))        #实例结构中包含__slots__,x,y,不能任意绑定属性
#print(dir(t))          #实例结构中包含__dict__,可任意绑定属性

t_s.x=1
t.x=1
print("t_s.x: %d"%t_s.x)
print("t.x: %d"%t.x)

t.y=1
print("t.y: %d"%t.y)
t_s.y=1
print("t_s.y: %d"%t_s.y)

运行结果为:

同时我们要注意的是,__slots__定义的属性只是对当前的实例起作用,对继承的子类不起作用。如果子类中也定义了__slots__的话,子类中允许定义的属性就是自身的__slots__加上父类的__slots__。

猜你喜欢

转载自blog.csdn.net/dxk_093812/article/details/83269701
今日推荐