Python魔法方法 容器部方法詳解
這篇文章主要介紹了Python魔法方法 容器部方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
為了加深印象,也為了以后能夠更好的回憶,還是記錄一下。
序列(類似集合,列表,字符串),映射(類似字典)基本上是元素的集合,要實現(xiàn)他們的基本行為(協(xié)議),不可變對象需要兩個協(xié)議,可變對象需要4個協(xié)議。
- __len__(self):返回元素的數(shù)量,(為不可變對象需要的協(xié)議之一)=====> len
- __iter__返回一個迭代器,具有了__next__方法后,給for使用。
- __contains__ 代表 in的意思 xx.__contains__ (22) ==>22 in xx一個效果
- __getitem__(self, key)或者__getitem__(self, index), 返回執(zhí)行輸入所關聯(lián)的值(為不可變對象需要的協(xié)議之一)
- __setitem__(self, key, values) 或者 __setitem__(self, index, values) , 設置指定輸入的值對應的values
- __delitem__ (self, key) 刪除指定key的值
- __missing__這個有意思,跟__getattr__有的一比,是找不到這個key,觸發(fā)條件。前面用列表測試了,暈死了(只對字典有效。)
- __del__, 析構函數(shù)當這個類不存在實例對象時執(zhí)行。
下面我編寫一個自定義類似列表的類,實例后該類默認前面有10個None參數(shù),且不能刪除前面5個空None。(隨口說的,開始寫了)
def check_index(index):
if index < 5:
raise IndexError('index must greater than 10')
class S_List:
def __init__(self):
self.ll = [None] * 10
def __len__(self): # 提取參數(shù)長度
return len(self.ll)
def __getitem__(self, index): # 取出參數(shù)
return self.ll[index]
def __setitem__(self, index, value): # 設置參數(shù)
check_index(index)
self.ll[index] = value
def __delitem__(self, index):
check_index(index)
self.ll.pop(index)
def __str__(self): # 打印對象時,輸出列表本身
return str(self.ll)
def __del__(self): # 沒有手工刪除在程序結束時釋放
print('我被釋放了!')
sl = S_List()
del sl[3]
print(isinstance(sl, S_List))
print(f'輸出原始數(shù)據(jù):{sl}')
sl[6] = 'six'
print(f'修改后原始數(shù)據(jù):{sl}')
print(f'隨便取一個值:{sl[1]}')
del sl[6]
print(f'第二次修改后原始數(shù)據(jù):{sl}')
del sl[3]
# sl[4] = 'oh'
print(sl)
正常輸出:
True 輸出原始數(shù)據(jù):[None, None, None, None, None, None, None, None, None, None] 修改后原始數(shù)據(jù):[None, None, None, None, None, None, 'six', None, None, None] 隨便取一個值:None 第二次修改后原始數(shù)據(jù):[None, None, None, None, None, None, None, None, None] [None, None, None, None, None, None, None, None, None] 我被釋放了!
報錯提示:
Traceback (most recent call last):
File "/Users/shijianzhong/Desktop/yunzuan_buy/study_base.py", line 81, in <module>
del sl[3]
File "/Users/shijianzhong/Desktop/yunzuan_buy/study_base.py", line 73, in __delitem__
check_index(index)
File "/Users/shijianzhong/Desktop/yunzuan_buy/study_base.py", line 53, in check_index
raise IndexError('index must greater than 10')
IndexError: index must greater than 10
我被釋放了!
這個是自定義的一個基本沒有什么方法的偽字典,不能增加元素,而且index,count等方法由于沒有寫入都無法使用。
好的方式是可以繼承l(wèi)ist或者dict的類,在里面對需要的條件進行修改限制,這樣的話,實例出來的對象可以繼承原來的全部方法。
插入一個直接不用初始化自定義變量,直接借用__dict__來實現(xiàn)偽字典型的取值復制。
class Ii:
def __getitem__(self, item):
return self.__dict__[item]
def __setitem__(self, key, value):
self.__dict__[key] = value
li = Ii()
li[3] = 5
print(li[3])
# 5
這次我可以正真的定義個超級列表,根據(jù)我的需要?,F(xiàn)在要求這個列表初始化有5個None元素,前面5個元素不能修改,后面添加的元素必須為str
def check_str(params):
if not isinstance(params, str):
raise ValueError('parameters must is string')
def check_index(index):
if index < 5:
raise IndexError('index must greater than 10')
class Super_List(list):
def __init__(self):
super(Super_List, self).__init__() # 調(diào)用父類初始化
self += [None] * 5 # 對初始化的參數(shù)進行修改
def append(self, *args): # 對append進行參數(shù)限制
for i in args:
check_str(i)
return super(Super_List, self).append(*args)
def insert(self, index, *args): # 對insert的參數(shù)(索引及插入元素)進行限制
check_index(index) # 判斷插入位置
for i in args:
check_str(i)
return super(Super_List, self).insert(index, *args)
def extend(self, *args): # 對擴張的列表元素進行判斷
temp = args[0]
for i in temp:
check_str(i)
super(Super_List, self).extend(*args)
def __delitem__(self, index): # 對del命令的索引進行判斷
check_index(index)
super(Super_List, self).__delitem__(index)
def clear(self): # 禁止使用clear命令
raise TypeError('No permission')
ss_l = Super_List()
print(ss_l)
ss_l.append('1')
ss_l.insert(5, 'a')
ss_l.extend(['a', 'b', 'c'])
ss_l.clear()
print(ss_l)
寫了快半個小時,感覺列表的增加與刪除命令很多,所有有一些命令沒有重寫,但邏輯還是一樣的。
如果向在有人訪問參數(shù)的時候,自動執(zhí)行某些命令,可以寫在__getitem__下面。
跟新后,添加一個__missing__感覺還是非常有意思的。
class Dict(dict):
def __init__(self, *args, **kwargs):
# self.x = 12
super(Dict, self).__init__(*args, **kwargs)
def __missing__(self, key):
self[key] = None
return self[key]
l = Dict(((1,2),(2,3)))
print(l)
print(l[8])
print(l)
{1: 2, 2: 3}
None
{1: 2, 2: 3, 8: None}
有點像字典的內(nèi)置方式setdefault,我看能不能改成一樣的。
已經(jīng)寫完了,通過[]取值。
# -*- coding: utf-8 -*-
class Dict(dict):
def __init__(self, *args, **kwargs):
super(Dict, self).__init__(*args, **kwargs)
def __missing__(self, item):
# 判斷進來的參數(shù)是不是字符串,如果是字符串說明就是對象主動調(diào)用__missing__進來的
# 非__getitem__導入的
if isinstance(item, str):
self[item] = 'Default Empty'
return self[item]
# 如果對象非字符串,明顯說明是__getitem__導入的,判斷長度就可以
else:
key, value = item
self[key] = value # 自身進行賦值
return self[key] # 返回value
def __getitem__(self, item):
if not isinstance(item, tuple): # 傳進來的item進行判斷,如果非元祖,直接調(diào)用父類綁定self方法返回
return super(Dict, self).__getitem__(item)
elif len(item) == 2 and isinstance(item, tuple): # 如果是元祖,又是2位長度的,進行賦值。其實感覺元祖判斷沒有好像也沒關系
k, _ = item
if k in self:
return super(Dict, self).__getitem__(k) # 如果k在self里面繼續(xù)調(diào)用父類綁定self方法返回
else:
res = self.__missing__(item) # 否則調(diào)用自身的__missing
return res
else:
raise TypeError('input pattern error') # 元素數(shù)量超過2個,直接報錯
l = Dict((('name','sidian'),('age',99)))
print(l)
print(l['name','wudian'])
print(l['addr','杭州'])
print(l['hobby'])
print(l)
{'name': 'sidian', 'age': 99}
sidian
杭州
Default Empty
{'name': 'sidian', 'age': 99, 'addr': '杭州', 'hobby': 'Default Empty'}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
python使用redis模塊來跟redis實現(xiàn)交互
這篇文章主要介紹了python使用redis模塊來跟redis實現(xiàn)交互,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-06-06
python使用tcp實現(xiàn)局域網(wǎng)內(nèi)文件傳輸
這篇文章主要介紹了python使用tcp實現(xiàn)局域網(wǎng)內(nèi)文件傳輸,文件包括文本,圖片,視頻等,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-07-07
Pycharm中Python環(huán)境配置常見問題解析
這篇文章主要介紹了Pycharm中Python環(huán)境配置常見問題,結合圖文形式分析了Pycharm中Python環(huán)境配置模塊路徑問題、虛擬環(huán)境創(chuàng)建、配置遠程服務器、連接數(shù)據(jù)庫等常見問題與操作方法,需要的朋友可以參考下2020-01-01
python利用蒙版摳圖(使用PIL.Image和cv2)輸出透明背景圖
這篇文章主要介紹了python利用蒙版摳圖(使用PIL.Image和cv2)輸出透明背景圖,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08
一文讓你徹底搞懂Python中__str__和__repr__
這篇文章主要介紹了Python中的__str__和__repr__的異同,__str__和__repr__是基本的內(nèi)置方法,文中有詳細的代碼示例,感興趣的同學可以參考閱讀下2023-05-05

