比如我們想定義乙個inttuple類,表示接受引數後,只取其中int型別,且大於0的,然後存為tuple型別
首先我們想到繼承父類tuple,然後修改一下:
class
inttuple
(tuple):
def__init__
(self,iterable)
:for i in iterable:
ifisinstance
(i,int
)and i>0:
super()
.__init__(i)
t = inttuple([1
,-2,
[1,2
],'abc'
])
而當我們這樣執行時,卻會發現報錯了,報錯顯示為typeerror: object.__init__() takes exactly one argument (the instance to initialize),
class
inttuple
(tuple):
def__init__
(self,iterable)
:print
(self)
t = inttuple([1
,-2,
[1,2
],'abc'
])
此時我們將上述迴圈刪除,直接列印,會發現此時,直接輸出的self就是(1,-2,[1,2],『abc』)
此時其實我們應該使用__new__方法,我們可以這樣理解他:__init__()負責將類例項化,__new__()負責製造這樣的乙個例項物件。
然後我們將**改為:
class
inttuple
(tuple):
def__new__
(cls,
*args,
**kwargs)
: f =
(i for i in iterable if
isinstance
(i,int
)and i >0)
return
super()
.__new__(cls, f)
t = inttuple([1
,-2,
[1,2
],'abc'])
print
(t)
此時我們再執行,即可得到我們需要的。
在例項情況多的情況下我們如何降低這些大量例項的記憶體開銷?
我們先定義兩個類
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'
,'dog'
) p2 = player2(
'0002'
,'cat'
)
__slots__來修飾屬性的話可以減少其記憶體開銷,那麼他具體是怎麼實現的呢。
我們分別用dir()檢視p1,p2的內部屬性,發現相差的有__dict__
__dict__指的是動態繫結屬性,即
p1.x =
3p2.y =
4
執行上述兩條操作的話,第一條是可以執行的,因為類player1無__slots__,可以進行這些動態繫結屬性的操作,而第二條不行,類player2只能修改uid,name,status,level這四個屬性。
而想要查詢記憶體使用情況的話,我們可以匯入sys庫,使用其中的getsizeof函式,
import sys
print
(sys.getsizeof(p1.__dict__)
)
即可
我們在用python執行檔案時應該都寫過with open(『***.txt』, 『r』) as f:這種語句,這種帶with的open語句自帶關閉就不需要我們再自行 f.close()去關閉,那麼with 語句能不能對類這些進行操作呢?
class
sample
(object):
deftext
(self)
:print
('111'
)with sample(
)as s:
s.text(
)
當我們這樣執行時,會報錯,提示我們缺少__enter__,而我們加上__enter__後又提示了我們缺少__exit__,當我們再把__exit__後,誒,就發現ok了。
class
sample
(object):
# 獲取資源
def__enter__
(self)
:print
('start'
)return self
deftext
(self)
:print
('111'
)# 釋放資源
def__exit__
(self, exc_type, exc_val, exc_tb)
:# 異常類
print
(exc_type)
# 異常值
print
(exc_val)
# 追蹤資訊
print
(exc_tb)
print
('end'
)with sample(
)as s:
s.text(
)
講到這就得在提到python中的上下文管理器
contextlib簡化上下文管理器
import contextlib
@contextlib.contextmanager
deffile_open
(filename)
:# *** __enter__ 函式
print
('file open'
)yield
# __exit__ 函式
print
('file close'
)with file_open(
'demo.txt'
)as f:
print
('file operation'
)
在匯入contextlib庫後使用裝飾器@contextlib.contextmanager
在yield{}上面的部分就相當於上個例子中的__enter__函式
而在yield{}下面的部分就相當於上個例子中的__exit__函式
在with部分即為執行的內容
類與物件深度問題
defnew cls 建立乙個類物件,自動執行,當期執行時如果沒有創造物件並且返回則不會執行 init 方法,因為 init 方法是只有物件被建立時才會自動呼叫。一般init會自動呼叫是因為物件被自動建立了,所有類的父類object有這個功能,噹噹你執行了 new 之後object不會在執行,所以假...
類與物件深度問題與解決技巧 3 上下文管理器
首先寫乙個簡單的異常處理 try f open demo.txt w 丟擲異常 raise typeerror 捕獲異常 except typeerror as e print typeerror f.close except valueerror as e print valueerror f.c...
類與物件(1)
類與物件 1 主函式 public class text 這裡定義乙個人的類 class person public void setage int age 建構函式做初始化 public person 當沒有建構函式時,計算機會預設乙個無引數建構函式 當程式設計師寫了乙個有引數的建構函式,系統就不...