學習筆記(抽象基類、上下文管理、多型的應用、節約記憶體的例項)
抽象基類
- 什麼是抽象類?
- 抽象類是一個特殊的類,它的特殊之處在於只能被繼承,不能被例項化.
- 抽象類的作用
- 從一堆類中抽取相同的內容,內容包括資料屬性和函式屬性。我的個人理解就是抽象基類就是一個框架模型。
- 抽象基類的繼承
- 繼承了抽象基類必須重寫指定的方法。
import abc
class F_file(metaclass=abc.ABCMeta):
all_type = 'file'
@abc.abstractmethod #定義抽象方法
def read(self):
pass
@abc.abstractmethod
def write(self):
pass
class TXT(F_file):
def read(self):
print('讀txt檔案')
def write(self):
print('寫入到txt檔案中')
a=TXT()
print(issubclass(TXT,F_file)) #True
print(isinstance(a,F_file)) #True
- 使用register方法註冊。
import abc
class A(metaclass=abc.ABCMeta):
all_title='file'
@abc.abstractmethod
def read(self):
pass
@abc.abstractmethod
def write(self):
pass
class B(object):
pass
A.register(B)
print(issubclass(B,A)) #True
自定義一個類的案例
我們想自定義一種新型別的元組,對於傳入的可迭代物件,我們只保留其中int型別且值大於0的元素。
例:
data = [12,-5,['tu',1],5,'8',1.1]
print(tuple(data))
#(12, -5, ['tu', 1], 5, '8', 1.1)
#新型別元組:
#new_tuple(data) =>(12,5)
思路:繼承元組並重寫方法
class new_tuple(tuple):
def __new__(cls, iterable):
f = (i for i in iterable if isinstance(i,int) and i > 0 )
return super().__new__(cls,f)
print(new_tuple(data))
上下文管理
-
同時包含 __enter__() 和 __exit__() 方法的物件就是上下文管理器。
-
__enter__(self):進入上下文管理器自動呼叫的方法。
-
__exit__(self, exc_type, exc_value, exc_traceback):退出上下文管理器自動呼叫的方法
class Get_info():
def __init__(self,name):
self.name = name
def __enter__(self):
print('獲取資源')
return self.name #將返回值作為as的物件
def __exit__(self,exc_type,exc_val,exc_tb):
print('錯誤型別:',exc_type)
print('錯誤值:',exc_val)
print('回溯錯誤:',exc_tb)
return True #返回值為True時丟擲錯誤但不會中斷程式
with Get_info('lh') as f:
print(f)
執行結果:
獲取資源
lh
釋放資源
錯誤型別: None
錯誤值: None
回溯錯誤: None
使用內建模組contextlib,@contextmanager讓我們通過編寫generator來簡化上下文管理。
import contextlib
@contextlib.contextmanager
def show_info(name):
#__enter__方法
file_name = open(name,'r',encoding='utf-8')
#yield
try:
yield file_name
except Exception as err:
print(err)
#__exit__()方法
finally:
file_name.close()
with show_info('test.txt') as f:
print(f.readline())
抽象基類的應用
import abc
import math
# from functools import total_ordering
# @total_ordering
class Shape(metaclass=abc.ABCMeta):
@abc.abstractmethod
def area(self):
pass
def __lt__(self, other):
return self.area() < other.area()
def __eq__(self, other):
return self.area() == other.area()
class Cricle(Shape):
def __init__(self,x):
self.x = x
def area(self):
return self.x ** 2 * math.pi
class Square(Shape):
def __init__(self,l):
self.l = l
def area(self):
return self.l ** 2
class Rectange(Shape):
def __init__(self,x,y):
self.x = x
self.y = y
def area(self):
return self.x * self.y
cricle=Cricle(5)
square=Square(6)
rectange=Rectange(4,9)
print(cricle < rectange)
print(square == rectange)
多型的應用
實現一個統一的獲取面積的函式
import math
class Cricle(object):
def __init__(self,x):
self.x = x
def get_area(self):
return self.x ** 2 * math.pi
class Rectange(object):
def __init__(self,x,y):
self.x = x
self.y = y
def get_area(self):
return self.x * self.y
class Square(object):
def __init__(self,x):
self.x = x
def get_area(self):
return self.x ** 2
cricle=Cricle(5)
rectange=Rectange(7,6)
square=Square(7)
shape_list=[cricle,rectange,square]
for i in shape_list:
print(i.get_area())
使用getattr方法實現
import math
class Cricle(object):
def __init__(self,x):
self.x = x
def get_area(self):
return self.x ** 2 * math.pi
class Rectange(object):
def __init__(self,x,y):
self.x = x
self.y = y
def get_Area(self):
return self.x * self.y
class Square(object):
def __init__(self,x):
self.x = x
def area(self):
return self.x ** 2
def get_all_area(object):
method_name = ['get_area','get_Area','area']
for name in method_name:
goal = getattr(object,name,None)
if goal:
return goal()
cricle=Cricle(5)
rectange=Rectange(7,6)
square=Square(7)
shape_list=[cricle,rectange,square]
area_list = list(map(get_all_area,shape_list))
print(area_list)
節約記憶體的例項
在遊戲開發中,有一個玩家類Player,每有一個線上玩家,在伺服器內則有一個player的例項,當線上的人數很多時,將產生大量例項(百萬級)。
如何降低這些大量例項的記憶體開銷?
-
由於Python中預設用一個字典來儲存一個物件的例項屬性,使得我們在執行時可以任意設定新屬性。如果建立成千上萬個這樣的小類,Python就會浪費掉很多記憶體,所以python中引入了 __slot__屬性。這個屬性的兩個作用:1、給類指定一個固定大小的空間存放屬性;2、無法給該類建立的例項新增新的屬性。
#首先建立兩個物件使用__dict__來檢視物件內的內容
class Player1(object):
pass
class Player2(object):
__slot__ = ()
pass
print(Player1.__dict__)
print(Player2.__dict__)
執行結果:
{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Player1' objects>, '__weakref__': <attribute '__weakref__' of 'Player1' objects>, '__doc__': None}
{'__module__': '__main__', '__slots__': (), '__doc__': None}
顯而易見,使用__slot__()後,物件中的屬性都由__slot__ : ()取代了。這時你可能是會說,雖然屬性看著確實少了,但是沒有說服力,那確實,下面我們拿資料來證明。
這裡我需要呼叫tracemalloc模組來對記憶體使用進行跟蹤
import tracemalloic
class Player1(object):
def __init__(self,name,uid,attribute=1,skill=2):
self.name = name
self.uid = uid
self.attribute = attribute
self.skill = skill
class Player2(object):
__slots__ = ('name','uid','attribute','skill')
def __init__(self,name,uid,attribute=1,skill=2):
self.name = name
self.uid = uid
self.attribute = attribute
self.skill = skill
#記憶體跟蹤
tracemalloc.start() #開始跟蹤記憶體分配
player1 = [Player1('haha',1,) for i in range(100000)] #size=15.3 MiB
# player2=[Player2('haha',1) for i in range(100000)] #size=7055 KiB
snapshot = tracemalloc.take_snapshot() #快照,當前記憶體分配
top = snapshot.statistics('filename') #快照物件的統計 監控檔案
for start in top:
print(start)
相關文章
- java多型抽象類例項Java多型抽象
- 抽象類特點 學習筆記抽象筆記
- GObject學習筆記(一)類和例項GoObject筆記
- JVM學習筆記——自動記憶體管理JVM筆記記憶體
- Objective C 記憶體管理(上)學習筆記Object記憶體筆記
- 抽象類的成員特點 學習筆記抽象筆記
- HttpModule學習總結例項應用-讀書筆記HTTP筆記
- 類的基礎學習筆記筆記
- XV6學習筆記(2) :記憶體管理筆記記憶體
- 作業系統——記憶體管理學習筆記作業系統記憶體筆記
- Object C學習筆記4-記憶體管理Object筆記記憶體
- Android學習之 記憶體管理機制與應用記憶體優化Android記憶體優化
- 2 Day DBA-管理Oracle例項-管理記憶體-關於記憶體管理Oracle記憶體
- 多項式學習筆記筆記
- 2 Day DBA-管理Oracle例項-管理記憶體-修改記憶體設定-自動記憶體管理Oracle記憶體
- Java學習筆記之介面和抽象類Java筆記抽象
- Python 3 學習筆記之類與例項Python筆記
- android 管理應用的記憶體Android記憶體
- AntDB記憶體管理之記憶體上下文之記憶體上下文機制是怎麼實現的記憶體
- 乞丐是如何節約Java記憶體的Java記憶體
- Spark學習——記憶體管理Spark記憶體
- Java應用程式中的記憶體洩漏及記憶體管理Java記憶體
- PHP 手冊 (類與物件) 學習筆記十:抽象類PHP物件筆記抽象
- iOS另類的記憶體管理iOS記憶體
- 《深入理解java虛擬機器》學習筆記2——Java記憶體溢位例項Java虛擬機筆記記憶體溢位
- scala學習筆記:控制抽象筆記抽象
- Web 開發學習筆記(5) — 抽象出 Page 類Web筆記抽象
- Python 學習筆記之類「物件導向,超類,抽象」Python筆記物件抽象
- 記憶體管理篇——實體記憶體的管理記憶體
- Solidity語言學習筆記————35、抽象合約和介面Solid筆記抽象
- C++學習體會:記憶體管理C++記憶體
- Python零基礎學習筆記(三十五)——記憶體修改Python筆記記憶體
- 《應用迴歸及分類》學習筆記1筆記
- 選擇介面還是抽象類?---應用例項說明介面與抽象類的應用場合(區別)抽象
- 多型記憶體圖解多型記憶體圖解
- Oracle 11gR2 ASM例項記憶體管理OracleASM記憶體
- Pooled Allocation(池式分配)例項——Keil 記憶體管理記憶體
- JVM學習-自動記憶體管理JVM記憶體