成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

Python面向對象魔法方法和單例模塊代碼實例

瀏覽:2日期:2022-08-01 11:10:52

魔法方法

​ 凡是在類內部定義,以“__開頭__結尾”的方法都稱之為魔法方法,又稱“類的內置方法”, 這些方法會在某些條件成立時觸發。

經常用到的雙下方法

__init__: 在調用類時觸發。 __delarttr__: __getattr__: 會在對象.屬性時,“屬性沒有”的情況下才會觸發。對象.__dict__[屬性]不會觸發__getattr__,會報keyerror; __getattribute__:會在對象.屬性時觸發,不管有沒有該屬性都會觸發; __setattr__: 會在 “對象.屬性 = 屬性值” 時觸發。即:設置(添加/修改)屬性會觸發它的執行; __del__: 當對象在內存中被釋放時,自動觸發執行,該方法會在最后執行。

class Uderline_func: x = 100 def __init__(self, y): print(’類加括號調用的時候觸發我!’) self.y = y # 當與__setattr__方法同時存在時,self.y = y并不會被加載到對象的名稱空間 # self[’y’] = y # TypeError: ’Uderline_func’ object does not support item assignment def general_func(self): print(’隨便定義的一個函數!’) # def __getattr__(self, item): # print(’只有對象獲取一個沒有的屬性值得時候觸發我!’) def __getattribute__(self, item): print(’類或對象無論獲取的屬性有沒有都會觸發我!且出現我,對象點一個沒有的屬性會覆蓋掉__getattr__,還會導致__setattr__函數報錯’) def __setattr__(self, key, value): print(’設置屬性的時候觸發我!’) # self.a = ’在對象名稱空間增加一個值!’ # 會一直觸發__setattr__,出現遞歸調用 self.__dict__[’a’] = ’在對象名稱空間增加一個值!’ def __delattr__(self, item): print(’刪除值得時候觸發我!’) def __del__(self): print(’程序運行完,被Python解釋器回收時,觸發我!’)# print(Uderline_func.__dict__) # 類在定義階段就已經創建好了類名稱空間,將其內部變量名和函數名塞進去u = Uderline_func(100) # 觸發__init__# print(u.__dict__) # {’y’: 100}# Uderline_func.z # 只會觸發__getattribute__u.z # 獲取沒有的屬性觸發__getattr__# u.name = ’zhang’ # 觸發__setattr__# del u.x # 對象不能刪除掉類中的屬性,但只要執行刪除操作,都會觸發__delattr__的執行 __str__: 會在打印對象時觸發。 __call__: 會在對象被調用時觸發。 __new__: 會在__init__執行前觸發。

class Uderline_func(): x = 100 # def __new__(cls, *args, **kwargs): # # print(’在__init__執行之前觸發我,造一個空對象!’) def __init__(self): print(’類加括號調用的時候觸發我!’) def __call__(self, *args, **kwargs): print(’對象加括號調用的時候觸發我!’) def __str__(self): print(’對象被打印的時候觸發我!’) return ’必須要寫return返回一個字符串!不然報錯'TypeError: __str__ returned non-string (type NoneType)'’u = Uderline_func()u()print(u)

__setitem__,__getitem,__delitem__

class Foo: def __init__(self,name): self.name=name def __getitem__(self, item): print(self.__dict__[item]) def __setitem__(self, key, value): self.__dict__[key]=value # self.age = value # 也可以給對象添加屬性 def __delitem__(self, key): print(’del obj[key]時,我執行’) self.__dict__.pop(key) def __delattr__(self, item): print(’del obj.key時,我執行’) self.__dict__.pop(item)f1=Foo(’sb’)f1[’age’]=18# print(f1.__dict__)f1[’age1’]=19# del f1.age1# del f1[’age’]f1[’name’]=’alex’f1.xxx = 111print(f1.__dict__) # {’name’: ’alex’, ’age’: 18, ’age1’: 19, ’xxx’: 111}

1.__slots__是什么:是一個類變量,變量值可以是列表,元祖,或者可迭代對象,也可以是一個字符串(意味著所有實例只有一個數據屬性)

2.引子:使用點來訪問屬性本質就是在訪問類或者對象的__dict__屬性字典(類的字典是共享的,而每個實例的是獨立的)

3.為何使用__slots__:字典會占用大量內存,如果你有一個屬性很少的類,但是有很多實例,為了節省內存可以使用__slots__取代

實例的__dict__

當你定義__slots__后,__slots__就會為實例使用一種更加緊湊的內部表示。實例通過一個很小的固定大小的數組來構建,而不是為每個實例定義一個字典,這跟元組或列表很類似。在__slots__中列出的屬性名在內部被映射到這個數組的指定小標上。使用__slots__一個不好的地方就是我們不能再給實例添加新的屬性了,只能使用在__slots__中定義的那些屬性名。

4.注意事項:__slots__的很多特性都依賴于普通的基于字典的實現。另外,定義了__slots__后的類不再 支持一些普通類特性了,比如多繼承。大多數情況下,你應該只在那些經常被使用到 的用作數據結構的類上定義__slots__比如在程序中需要創建某個類的幾百萬個實例對象 。

關于__slots__的一個常見誤區是它可以作為一個封裝工具來防止用戶給實例增加新的屬性。盡管使用__slots__可以達到這樣的目的,但是這個并不是它的初衷。 更多的是用來作為一個內存優化工具。

class Foo: __slots__ = ’x’f1 = Foo()f1.x = 1f1.y = 2 # 報錯print(f1.__slots__) # f1不再有__dict__屬性print(f1.x) #依然能訪問class Bar: __slots__ = [’x’, ’y’]n = Bar()n.x, n.y = 1, 2n.z = 3 # 報錯

__doc__:查看類中注釋

class Foo: ’我是描述信息’ passprint(Foo.__doc__)class Foo: ’我是描述信息’ passclass Bar(Foo): passprint(Bar.__doc__) #該屬性無法繼承給子類

__module__和__class__

__module__:表示當前操作的對象在那個模塊

 __class__:表示當前操作的對象的類是什么

class C: def __init__(self): self.name = ‘SB’from lib.aa import Cobj = C()print obj.__module__ # 輸出 lib.aa,即:輸出模塊print obj.__class__ # 輸出 lib.aa.C,即:輸出類

__enter__和__exit__

我們知道在操作文件對象的時候可以這么寫

with open(’a.txt’) as f:’代碼塊’

上述叫做上下文管理協議,即with語句,為了讓一個對象兼容with語句,必須在這個對象的類中聲明__enter__和__exit__方法

class Open: def __init__(self,name): self.name=name def __enter__(self): print(’出現with語句,對象的__enter__被觸發,有返回值則賦值給as聲明的變量’) # return self def __exit__(self, exc_type, exc_val, exc_tb): print(’with中代碼塊執行完畢時執行我啊’)with Open(’a.txt’) as f: print(’=====>執行代碼塊’) # print(f,f.name) ’’’出現with語句,對象的__enter__被觸發,有返回值則賦值給as聲明的變量=====>執行代碼塊with中代碼塊執行完畢時執行我啊’’’

exit()中的三個參數分別代表異常類型,異常值和追溯信息,with語句中代碼塊出現異常,則with后的代碼都無法執行

class Open: def __init__(self,name): self.name=name def __enter__(self): print(’出現with語句,對象的__enter__被觸發,有返回值則賦值給as聲明的變量’) def __exit__(self, exc_type, exc_val, exc_tb): print(’with中代碼塊執行完畢時執行我啊’) print(exc_type) print(exc_val) print(exc_tb)with Open(’a.txt’) as f: print(’=====>執行代碼塊’) raise AttributeError(’***著火啦,救火啊***’)print(’0’*100) #------------------------------->不會執行’’’出現with語句,對象的__enter__被觸發,有返回值則賦值給as聲明的變量=====>執行代碼塊with中代碼塊執行完畢時執行我啊<class ’AttributeError’>***著火啦,救火啊***<traceback object at 0x000000000A001E88>Traceback (most recent call last): File 'G:/Python代碼日常/第一階段/1階段/面向對象/test.py', line 52, in <module> raise AttributeError(’***著火啦,救火啊***’)AttributeError: ***著火啦,救火啊***’’’

如果__exit()返回值為True,那么異常會被清空,就好像啥都沒發生一樣,with后的語句正常執行

class Open: def __init__(self,name): self.name=name def __enter__(self): print(’出現with語句,對象的__enter__被觸發,有返回值則賦值給as聲明的變量’) def __exit__(self, exc_type, exc_val, exc_tb): print(’with中代碼塊執行完畢時執行我啊’) print(exc_type) print(exc_val) print(exc_tb) return True with Open(’a.txt’) as f: print(’=====>執行代碼塊’) raise AttributeError(’***著火啦,救火啊***’)print(’0’*100) #------------------------------->會執行

class Open: def __init__(self,filepath,mode=’r’,encoding=’utf-8’): self.filepath=filepath self.mode=mode self.encoding=encoding def __enter__(self): # print(’enter’) self.f=open(self.filepath,mode=self.mode,encoding=self.encoding) return self.f def __exit__(self, exc_type, exc_val, exc_tb): # print(’exit’) self.f.close() return True def __getattr__(self, item): return getattr(self.f,item)with Open(’a.txt’,’w’) as f: print(f) f.write(’aaaaaa’) f.wasdf #拋出異常,交給__exit__處理

用途或者說好處:

1.使用with語句的目的就是把代碼塊放入with中執行,with結束后,自動完成清理工作,無須手動干預

2.在需要管理一些資源比如文件,網絡連接和鎖的編程環境中,可以在__exit__中定制自動釋放資源的機制,你無須再去關系這個問題,這將大有用處

單例模式

單例模式:多次實例化的結果指向同一個實例

方式1

# @classmethod(用類綁定方法)import settingsclass MySQL: __instance=None def __init__(self, ip, port): self.ip = ip self.port = port @classmethod def from_conf(cls): if cls.__instance is None: cls.__instance=cls(settings.IP, settings.PORT) return cls.__instanceobj1=MySQL.from_conf()obj2=MySQL.from_conf()obj3=MySQL.from_conf()# obj4=MySQL(’1.1.1.3’,3302)print(obj1)print(obj2)print(obj3)# print(obj4)

方式2

# 用類裝飾器import settingsdef singleton(cls): _instance=cls(settings.IP,settings.PORT) def wrapper(*args,**kwargs): if len(args) !=0 or len(kwargs) !=0: obj=cls(*args,**kwargs) return obj return _instance return wrapper@singleton #MySQL=singleton(MySQL) #MySQL=wrapperclass MySQL: def __init__(self, ip, port): self.ip = ip self.port = port# obj=MySQL(’1.1.1.1’,3306) #obj=wrapper(’1.1.1.1’,3306)# print(obj.__dict__)obj1=MySQL() #wrapper()obj2=MySQL() #wrapper()obj3=MySQL() #wrapper()obj4=MySQL(’1.1.1.3’,3302) #wrapper(’1.1.1.3’,3302)print(obj1)print(obj2)print(obj3)print(obj4)

方式3

# 調用元類import settingsclass Mymeta(type): def __init__(self,class_name,class_bases,class_dic): #self=MySQL這個類 self.__instance=self(settings.IP,settings.PORT) def __call__(self, *args, **kwargs): # self=MySQL這個類 if len(args) != 0 or len(kwargs) != 0: obj=self.__new__(self) self.__init__(obj,*args, **kwargs) return obj else: return self.__instanceclass MySQL(metaclass=Mymeta): #MySQL=Mymeta(...) def __init__(self, ip, port): self.ip = ip self.port = portobj1=MySQL()obj2=MySQL()obj3=MySQL()obj4=MySQL(’1.1.1.3’,3302)print(obj1)print(obj2)print(obj3)print(obj4)

方式4

# 利用模塊多次導入只產生一次名稱空間,多次導入只沿用第一次導入成果。def f1(): from singleton import instance print(instance)def f2(): from singleton import instance,My SQL print(instance) obj=MySQL(’1.1.1.3’,3302) print(obj)f1()f2()

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Python 編程
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
午夜国产精品视频| 国产精品v欧美精品v日韩精品| 久久成人综合网| 国产精品二区在线| 91精品国产综合久久精品图片| 夜夜操天天操亚洲| www.日韩大片| 欧美性受极品xxxx喷水| 亚洲国产精品尤物yw在线观看| 欧美精品午夜| 欧美mv和日韩mv国产网站| 韩国精品在线观看| 亚洲欧美日韩在线综合| 亚洲欧洲综合另类在线| 午夜精品久久| 337p粉嫩大胆色噜噜噜噜亚洲| 精品亚洲成a人在线观看| 久久一区亚洲| 亚洲精品videosex极品| 欧美三级免费| 久久色视频免费观看| 久久亚洲精品国产精品紫薇| 精品一区二区三区的国产在线播放| 校园春色综合网| 亚洲综合男人的天堂| 极品中文字幕一区| 国产精品美女一区二区在线观看| 成人教育av在线| 欧美日韩精品一区二区三区| 日本少妇一区二区| 久久久精品网| 亚洲成av人片www| 亚洲一区免费看| 亚洲国产毛片aaaaa无费看| 国产亚洲毛片| 亚洲影视在线播放| 99视频精品免费观看| 中文字幕中文字幕一区二区| 午夜电影亚洲| 国产精品区一区二区三区| 欧美精品亚洲精品| 欧美老年两性高潮| 国精产品一区一区三区mba桃花 | 激情伊人五月天久久综合| 日本道色综合久久| 老司机精品视频导航| 欧美日韩一区二区三区在线看| 精品一区二区久久久| 在线播放一区二区三区| 精品在线播放免费| 欧美色视频在线| 国产美女娇喘av呻吟久久| 777午夜精品免费视频| 成人午夜av电影| 久久久久久影视| 欧美日韩国产亚洲一区| 国产精品五月天| 亚洲性图久久| 亚洲一区二区视频在线观看| 美女被久久久| 秋霞午夜鲁丝一区二区老狼| 欧美日韩精品免费| 国产成人av电影免费在线观看| 欧美成人精品高清在线播放| 成人美女视频在线观看18| 精品国产乱码久久久久久蜜臀| 国产日韩v精品一区二区| 国产精品草草| 一区二区三区高清不卡| 老鸭窝毛片一区二区三区| 亚洲v日本v欧美v久久精品| 久久久久久久久久久久久久一区 | 亚洲精品国产视频| 欧美国产视频在线观看| 欧美第一区第二区| 麻豆国产欧美一区二区三区| 日韩精品电影在线| 91福利在线免费观看| 国产一区在线观看视频| 日韩你懂的在线观看| 黑丝一区二区三区| 亚洲一区二区三区在线| 欧美性大战xxxxx久久久| 成人做爰69片免费看网站| 国产嫩草影院久久久久| 亚洲专区在线| 精品一区二区三区蜜桃| 久久精品夜色噜噜亚洲a∨| 日韩视频在线一区二区三区| 亚洲精品国产一区二区精华液| 色视频成人在线观看免| 粗大黑人巨茎大战欧美成人| 中文字幕亚洲视频| 色噜噜久久综合| 大胆欧美人体老妇| 樱花影视一区二区| 欧美久久免费观看| 在线精品观看| 久久综合综合久久综合| 精品免费视频.| 一区视频在线| 美日韩一区二区| 久久久久9999亚洲精品| 久久不射中文字幕| 狠狠网亚洲精品| 久久久夜色精品亚洲| 国产美女一区| 国产一区二区h| 中文字幕在线不卡国产视频| 欧美日韩一区二区三区高清 | 久久免费黄色| 日韩电影一区二区三区| 精品久久久久久最新网址| 国产亚洲高清视频| 国产91丝袜在线播放| 亚洲欧美日韩一区二区三区在线观看| 久久亚洲电影| 不卡的av中国片| 亚洲国产人成综合网站| 精品久久一区二区三区| 夜夜精品视频| 国产精品一区二区久久不卡| 91精品综合久久久久久| 日韩视频久久| 国产精品亚洲人在线观看| 亚洲区小说区图片区qvod| 69堂精品视频| 免费一区二区视频| 国产精品美女久久久久高潮| 欧美亚洲动漫精品| 国产精品多人| 国内精品久久久久影院色| 亚洲色图视频网| 欧美一区二区三区四区五区| 国产日韩综合| 99riav久久精品riav| 蜜臀av一区二区| **欧美大码日韩| 欧美不卡在线视频| 在线国产电影不卡| 海角社区69精品视频| 国产盗摄一区二区| 亚洲成人先锋电影| 国产午夜精品美女毛片视频| 欧美日韩一区小说| 免费亚洲视频| 99re6这里只有精品视频在线观看| 日本va欧美va精品| **欧美大码日韩| 精品国精品国产| 欧美午夜影院一区| 国产精品推荐精品| 欧美日韩亚洲三区| 成人亚洲一区二区一| 天堂午夜影视日韩欧美一区二区| 欧美二区在线观看| 欧美日本一区二区高清播放视频| 紧缚捆绑精品一区二区| 亚洲精品高清视频在线观看| 久久伊人蜜桃av一区二区| 欧洲视频一区二区| 国产欧美日韩一区| 91香蕉视频黄| 国产精品一线二线三线精华| 热久久国产精品| 日韩黄色一级片| 午夜国产精品一区| 亚洲黄一区二区三区| 亚洲欧洲国产专区| 国产欧美日韩久久| 日韩精品一区二区在线观看| 欧美麻豆精品久久久久久| 一本到不卡免费一区二区| 亚洲欧美国产精品桃花| 国产精品久久久久久久久久妞妞| 国内精品福利| 国产精品国码视频| 欧美在线91| 91网站视频在线观看| 91丨九色丨尤物| 97se亚洲国产综合在线| 97久久精品人人做人人爽 | 亚洲国产成人私人影院tom | 国产精品影视天天线| 亚洲欧美日韩一区| 国产精品网曝门| 91精品国产黑色紧身裤美女| 久久久福利视频| 精品999网站| 亚洲国产精品一区二区第一页 | 欧美日韩一级二级| 午夜在线视频一区二区区别| 亚洲私人影院| 91色视频在线| 国产成人av电影免费在线观看| 激情五月激情综合网| 亚洲第一狼人社区| 日本最新不卡在线| 午夜精品福利一区二区三区av | 91精品啪在线观看国产60岁|