python有几种打开方式_Python中几个以“__”开头的方法介绍总结
本文我們來看談 Python 中的特殊方法 __dir__, __slots__, __weakref____missing__, __contains__ 的簡單介紹總結。
__dir__ -> 看個小例子就知道了
In [1]: class T(object):
...: pass
...:
In [2]: t = T()
In [3]: t.
啥也沒有...
In [4]: class T2(object):
...: def __dir__(self):
...: return ['a', 'b']
...:
In [5]: t = T2()
In [6]: t.
t.a t.b
In [7]: dir(t)
Out[7]: ['a', 'b']
看出來了把, 不解釋, 但是這個__dir__是相對于類的實例有效果的.
__slots__
這個在我初學python的時候就被模糊了, 原來的理解是它的出現替代了__dict__,也就是說你只能給__slots__ 這個變量列表項的屬性賦值. 對外的接口減少了,也安全了. 后來看了這篇Saving 9 GB of RAM with Python’s slots. 好久不做運維了,在生產環境究竟怎么樣我無法定論, 也提到了,在對象實例很多的時候他能幫助減少內存, 詳見https://www.safaribooksonline.com/library/view/python-cookbook-3rd/9781449357337/ch08s04.html. 這里來個小實驗(在Hacker News也被討論過https://news.ycombinator.com/item?id=6750187)
代碼例子(我對細節做注釋):
# coding=utf-8
import sys
from itertools import starmap, product
class SlotTest(object):
# __slots__ = ['x', 'y', 'z'] 主要對比去掉這句和包含這句程序內存占用
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def __str__(self):
return "{} {} {}".format(self.x, self.y, self.z)
p = product(range(10000), range(20), [4]) # 創建0-1000 & 0-20 & 4 的笛卡爾積
a = list(starmap(SlotTest, p)) # 相當于對每個SlotTest實例化,實例化的格式是p的長度
print a[0]
sys.stdin.read(1)
結果對比:
$pmap -x `ps -ef|grep test_slot.py|grep -v grep|awk '{print $2}'`|grep total # 未使用__slots__
total kB 103496 76480 73728
$pmap -x `ps -ef|grep test_slot.py|grep -v grep|awk '{print $2}'`|grep total # 使用了__slots__
total kB 49960 22888 20136
結果很明顯,內存占用減少了很多…
__weakref__ 弱引用
首先先說下weakref: 弱引用,與強引用相對,是指不能確保其引用的對象不會被垃圾回收器回收的引用。一個對象若只被弱引用所引用,則被認為是不可訪問(或弱可訪問)的,并因此可能在任何時刻被回收. 在Python中,當一個對象的引用數目為0的時候,才會被從內存中回收. 但是被循環引用呢?
In [1]: import weakref
In [2]: import gc
In [3]: class Obj(object):
...: def a(self):
...: return 1
...:
In [4]: obj = Obj()
In [5]: s = obj
In [6]: gc.collect() # 不可達引用對象的數量
Out[6]: 3
In [7]: print s is obj
True
In [8]: obj = 1 # 最初的被引用的對象改變了.
In [9]: gc.collect()
Out[9]: 0
In [10]: s is None # s還是指向了Obj 引用計數為1
Out[10]: False
In [11]: s
Out[11]: <__main__.Obj at 0x2b36510>
----華麗的分割一下
In [12]: obj = Obj()
In [13]: r = weakref.ref(obj) # 讓obj變成那個弱引用
In [14]: gc.collect()
Out[14]: 211
In [15]: r() is obj
True
In [16]: obj = 1
In [17]: gc.collect()
Out[17]: 0
In [18]: r() is None # 弱引用計數器沒有增加,所以當obj不在引用Obj的時候,Obj對象就被釋放了
Out[18]: True
好吧, 我的總結是弱引用是個好東西, 但是加了__slots__就不支持弱引用了. 所以需要__weakref__
In [9]: class T3(object):
...: __slots__ = []
...:
In [10]: class T4(object):
....: __slots__ = '__weakref__' # 這樣就支持了weakref
....:
In [11]: import weakref
In [12]: t3 = T3()
In [13]: t4 = T4()
In [14]: weakref.ref(t3)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in ()
----> 1 weakref.ref(t3)
TypeError: cannot create weak reference to 'T3' object
In [15]: weakref.ref(t4)
Out[15]:
__contains__ 判斷某值 in/not in 實例
In [1]: class NewList(object):
...: def __init(self, values):
...: self.values = values
...: def __contains__(self, value):
...: return value in self.values
...:
In [2]: l = NewList([1, 2, 3, 4])
In [3]: 4 in l
Out[3]: True
In [4]: 10 in l
Out[4]: False
__missing__
最初看這個特殊方法是看python標準庫的源碼的時候(collections#L421):
class Counter(dict):
...
def __missing__(self, key):
'The count of elements not in the Counter is zero.'
# Needed so that self[missing_item] does not raise KeyError
return 0
什么意思呢?
In [6]: c = collections.Counter({'a':1})
In [7]: c['b'] # 沒有鍵的count設置默認值0
Out[7]: 0
很多人可能看過這個(關于defaultdict的ppt)[http://discorporate.us/jek/talks/defaultdict/]. 內容就不說了, 講的非常好.
原文:http://www.111cn.net/phper/python/79549.htm
總結
以上是生活随笔為你收集整理的python有几种打开方式_Python中几个以“__”开头的方法介绍总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: m3u8转mp4缓存合并工厂_多线程m3
- 下一篇: python数据分析pandas_Pyt