[Dynamic Language] Python __slots__ 限制绑定属性
Python 是一门动态语言,可以在运行过程中,修改对象的属性和增删方法。任何类的实例对象包含一个字典__dict__, Python通过这个字典将任意属性绑定到对象上。有时候我们只想使用固定的对象,而不想任意绑定对象,这时候我们可以定义一个属性名称集合,只有在这个集合里的名称才可以绑定。__slots__就是完成这个功能的。
test code
1 #!/usr/bin/env python
2 #_*_ coding:utf-8 _*_
3
4 class test_slot(object):
5 __slots__ = "width", "height"
6
7 def width(self):
8 print "width"
9
10
11 class test(object):
12 def amethod(self):
13 print "amethod"
ipython执行代码导入
In [1]: from test import *
In [2]: dir(test_slot)
Out[2]:
['__class__',
'__slots__',
'__str__',
'height',
'width']
In [3]: dir(test)
Out[3]:
['__class__',
'__weakref__',
'amethod']
可以看到 test_slot 类结构里面已经有height和width属性了。
下面我们继续查看两个实例对象结构里都有什么吧
In [4]: s = test_slot()
In [5]: t = test()
In [11]: dir(s)
Out[11]:
['__class__',
'__delattr__',
'__doc__',
'__slots__',
'height',
'width']
In [12]: dir(t)
Out[12]:
['__class__',
'__delattr__',
'__dict__',
'__doc__',
'amethod']
看到了吧, test_slot 的实例s 没有字典__dict__,多了__slots__属性,这样就不能任意绑定属性,只能绑定__slots__属性名称集合里的同名属性了。
我们来测试一把,先给两个实例的赋__slots__里面有的 height 属性,当然对t来说是新加属性。
In [7]: s.height = 1
In [8]: t.height = 0
赋值都没有问题。
下面再试一下不在__slots__里的属性名.
In [9]: s.abeen = "abeen" //和预期的一样,失败了。
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/home/abeen/learn_test/test/<ipython console> in <module>()
AttributeError: 'test_slot' object has no attribute 'abeen'
In [10]: t.abeen = "abeen" //正常运行