高階程式設計技巧 學習筆記
1.1、問題
如何降低這些大量例項的記憶體開銷?(動態繫結屬性問題)
1.2、解決方案
定義類的__slots__
屬性,宣告例項有哪些屬性(關閉動態繫結屬性)
import sys
# 兩個類, player1 開啟動態繫結, player2 關閉動態繫結
class player1(object):
def __init__(self, uid, name,
status=0
,level=1
): self.uid = uid
self.name = name
self.
status
=status
self.
level
=level
class player2(object):
# 相當於實現規定了 __init__ 方法只能包含哪些屬性
__slots__ =
('uid'
,'name'
,'status'
,'level'
) def __init__(self, uid, name,
status=0
,level=1
): self.uid = uid
self.name = name
self.
status
=status
self.
level
=level
# 例項化
p1 = player1(
'0001'
,'p1'
)p2 = player2(
'0002'
,'p2'
)# 開啟動態繫結
p1.x =
6p1.__dict__[
'y']=7
print
(p1.__dict__)
# 關閉動態繫結, 報錯
p2.y =
7# 檢視占用的記憶體, 發現 '動態繫結屬性的操作' 所佔記憶體多得多
print
(sys.getsizeof(p1.__dict__)
)print
(sys.getsizeof(p1.name)
)print
(sys.getsizeof(p1.uid)
)
1.3、tracemalloc 模組
import sys
import tracemalloc
class player1(object):
def __init__(self, uid, name,
status=0
,level=1
): self.uid = uid
self.name = name
self.
status
=status
self.
level
=level
class player2(object):
__slots__ =
('uid'
,'name'
,'status'
,'level'
) def __init__(self, uid, name,
status=0
,level=1
): self.uid = uid
self.name = name
self.
status
=status
self.
level
=level
p1 = player1(
'0001'
,'p1'
)p2 = player2(
'0002'
,'p2'
)# # 跟蹤記憶體的使用
tracemalloc.
start()
# 分別執行以下兩句
p1 =
[player1(1,
2,3)
for _ in range(
100000)]
# 20.6 mib
# p2 = [player2(1, 2, 3) for _ in range(100000)] # 7837 kib
end= tracemalloc.take_snapshot(
)# top = end.statistics('lineno') # 分析每一行**
top=
end.
statistics
('filename'
)# 分析整個檔案
for stat in
top[:10
]: print
(stat)
防止jQuery on多次繫結
button click function 引數描述 event 必需。規定要從被選元素移除的乙個或多個事件或命名空間。由空格分隔多個事件值。必須是有效的事件。selector 可選。規定新增事件處理程式時最初傳遞給 on 方法的選擇器。function eventobj 可選。規定當事件發生時執行...
靜態繫結和動態繫結
c 中,非虛函式都是靜態繫結,而虛函式卻是動態繫結。為了能夠更清楚地了解靜態繫結與動態繫結,我們可以看下面這個例子 include using namespace std class b 那麼兩次呼叫fun 函式是否相同呢?當然,如果d中沒有定義fun 函式 如例子中 那麼兩次呼叫的行為肯定會是一樣...
靜態繫結和動態繫結
物件的靜態型別 物件在宣告是採用的型別,在編譯期確定 物件的動態型別 當前物件所指的型別,在執行期決定,物件的動態型別可以更改,但靜態型別無法更改。靜態繫結 繫結的是物件的靜態型別,某特性 比如函式 依賴於物件的靜態型別,發生在編譯期。動態繫結 繫結的是物件的動態型別,某特性 比如函式 依賴於物件的...