Python __slots__

了解slots

slots可以用来限制对象的属性,如没有使用solt可以对对象添加任意属性,
属性被放置在对象的dict字典中,实例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return self.name + ':' + str(self.age)
if __name__ == '__main__':
p1 = Person('tom', 20)
#p1.com = 'baidu'
#print p1.com
print p1.__dict__
print type(p1.__dict__)
print p1.__dict__.__sizeof__()

运行结果如下:

1
2
3
{'age': 20, 'name': 'tom'}
<type 'dict'>
248

使用slots,用来限制对象的属性,此时,属性放置在一个slots的列表里面
实例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#coding=utf-8
class Person(object):
__slots__ = ['name', 'age']
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return self.name + ':' + str(self.age)
if __name__ == '__main__':
p1 = Person('tom', 20)
print p1
# 此时无法给对象添加其他属性
# p1.com = 'baidu'
print dir(p1)
print p1.__slots__
print type(p1.__slots__)
print p1.__slots__.__sizeof__()

运行结果如下:

1
2
3
4
5
tom:20
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'age', 'name']
['name', 'age']
<type 'list'>
56

可以看出,使用slots的话,可以节省一些内存空间,适合大量的建立对象适合使用。
比如,在爬虫系统中,需要通过解析页面产生大量的中间url进行抓取,这时候,这种中间url的类
可以按照以下方式定义,从而节省些内存:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Link(object):
"""Link objects represent an extracted link by the LinkExtractor."""
__slots__ = ['url', 'text', 'fragment', 'nofollow']
def __init__(self, url, text='', fragment='', nofollow=False):
self.url = url
self.text = text
self.fragment = fragment
self.nofollow = nofollow
def __eq__(self, other):
return self.url == other.url and self.text == other.text and \
self.fragment == other.fragment and self.nofollow == other.nofollow
def __hash__(self):
return hash(self.url) ^ hash(self.text) ^ hash(self.fragment) ^ hash(self.nofollow)
def __repr__(self):
return 'Link(url=%r, text=%r, fragment=%r, nofollow=%r)' % \
(self.url, self.text, self.fragment, self.nofollow)

参考:
http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0013868200605560b1bd3c660bf494282ede59fee17e781000
http://blog.jobbole.com/52420/
http://programtalk.com/vs2/?source=python/11662/scrapy/scrapy/link.py