1、雙下方法 定義:雙下方法是特殊方法,它是解釋器提供的 由雙下劃線加方法名加雙下劃線 方法名的具有特殊意義的方法,雙下方法主要是python源碼程式員使用的,我們在開發中儘量不要使用雙下方法,但是深入研究雙下方法,更有益於我們閱讀源碼。 (1)調用:不同的雙下方法有不同的觸發方式, __ len_ ...
1、雙下方法
定義:雙下方法是特殊方法,它是解釋器提供的 由雙下劃線加方法名加雙下劃線 方法名的具有特殊意義的方法,雙下方法主要是python源碼程式員使用的,我們在開發中儘量不要使用雙下方法,但是深入研究雙下方法,更有益於我們閱讀源碼。
(1)調用:不同的雙下方法有不同的觸發方式,
<1> __ len__ -- len() 觸發
class A(object):
def __init__(self,name):
self.name = name
print("觸發了__init__")
def __len__(self): # len() 觸發
print("走這裡")
return len(self.name) # return len("xqrqwr") str中__len__
# 必須有返回值,返回值的類型必須是整型
a = A("xqrqwr")
print(len(a))
# str
a = "12345" # str這個類的實例
lst = [1,2,3,4,4,5,5,5,5] # list這個類的實例
print(len(a))
print(len(lst))
<2> __ hash__ --hash() 觸發
class A(object):
def __init__(self,name,age):
self.name = name
self.age = age
def __hash__(self): # hash()
hash({1,2,345}) # 可變數據類,不可數據類型
return 1
# 必須有返回值,返回值的類型必須是整型
a = A("meet",25)
print(hash(a))
<3> __ str__ --print 或者 str() 觸發
class A:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def __str__(self): # print 觸發 str()
print(111)
return f"姓名:{self.name} 年齡:{self.age} 性別:{self.sex}"
# 必須有返回值,返回值的類型必須是字元串
a = A("mee",20,"男")
a1 = A("mee1",200,"男1")
str(a)
print(a)
print(a1)
# 以下對比:
a = A("mee",20,"男")
a1 = A("mee2",200,"女")
print(f"姓名:{a.name} 年齡:{a.age} 性別:{a.sex}") # "姓名:meet 年齡:20 性別:男"
print(f"姓名:{a1.name} 年齡:{a1.age} 性別:{a1.sex}") # "姓名:meet2 年齡:200 性別:女"
<4> __ repr__ --print 或者 %r 觸發
class A:
def __init__(self):
pass
def __repr__(self): # print觸發 %r
print(1111)
return "天魔"
def __str__(self): # str 優先順序高於 repr 兩個都存在就只執行str
return "小元"
a = A()
print("%r"%(a))
<5> __ call__ --對象調用時觸發,對象後加括弧即:對象() 或者 類()()
class A:
def __init__(self):
pass
def __call__(self, *args, **kwargs): # 對象()時調用的__call__
print("走我")
print(*args, **kwargs)
a = A()
a()
<6> __ eq__ 等於
class A(object):
def __init__(self,name,age):
self.name = name
self.age = age
def __eq__(self, other): # a == a1
if self.name == other.name:
return True
else:
return False
a = A("mee",56)
a1 = A("mee",108)
print(a == a1)
<7> __ del__ 構造方法,當對象在記憶體中被釋放時,自動觸發執行
此方法一般情況下無需定義,因為python是一門高級語言,程式員在使用時無需關心記憶體的分配和釋放,因為記憶體的分配和釋放都是交給python解釋器類執行,所以,析構函數的調用是由解釋器在進行垃圾回收時自動觸發執行的。
class A:
def __init__(self):
pass
def __del__(self): del 觸發
print("刪除時執行我")
a = A()
import time
time.sleep(5)
del a
a = 1
b = a
a = b
垃圾回收機制:
# 80 5/s
# 引用計數
# 標記清除
# 分袋回收 袋一:10 2/h 袋二: 5/3 4h 袋三: 3 20h
<8> __ item__ 系列 可以像操作字典一樣操作實例方法
dic["鍵"] = 值
del dic["鍵"]
dic["鍵"]
class A:
def __init__(self,name,age):
self.name = name
self.age = age
def __getitem__(self, item):
print(self.__dict__)
print(self.__dict__[item]) # self.__dict__ 獲取的就是字典
def __setitem__(self, key, value):
self.__dict__[key] = value
def __delitem__(self, key):
del self.__dict__[key]
a = A("meet",58)
a["sex"] = "男"
a["sex"]
del a["sex"]
print(a.__dict__)
<9> __ new__ 單例模式(工廠模式)
單例模式是一種常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例類的特殊類。通過單例模式可以保證系統中一個類只有一個實例而且該實例易於外界訪問,從而方便對實例個數的控制並節約系統資源。如果希望在系統中某個類的對象只能存在一個,單例模式是最好的解決方案。
class A(object):
def __init__(self,name): # 初始化
self.name = name
print("我是__init__,先走我")
def __new__(cls, *args, **kwargs):
print("我是__new__,先走我")
return "啦啦啦"
a = A("meet")
print("我是誰:",a)
'''
遇到問題沒人解答?小編創建了一個Python學習交流QQ群:579817333
尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書!
'''
class A(object):
def __init__(self,name): # 初始化
self.name = name
print("我是__init__,先走我")
def __new__(cls, *args, **kwargs):
obj = object.__new__(A)
print("我在哪:",obj)
return obj # obj == __init__()
a = A("meet")
print("我是誰:",a)
class A(object):
def __init__(self,name): # 初識化
self.name = name
def __new__(cls, *args, **kwargs):
obj = object.__new__(A) # 調用的是object類中的__new__ ,只有object類中的__new__能夠創建空間
return obj #本質: obj == __init__() return __init__() # 觸發了__init__方法
a = A("mee") # a是對象的記憶體地址
a1 = A("天魔") # a是對象的記憶體地址
a2 = A("天陽") # a是對象的記憶體地址
print(a.name)
print(a1.name)
print(a2.name)
# 先執行__new__方法再執行__init__方法
class A:
__a = None #__a = 0x000001F346079FD0
def __init__(self,name,age):
self.name = name
self.age = age
def __new__(cls, *args, **kwargs):
if cls.__a is None:
obj = object.__new__(cls)
cls.__a = obj
return cls.__a
a = A("mee",123) # 地址0x000001F346079FD0
a1 = A("天魔",11)
print(a.name)
print(a1.name)
單例模式:不管創建多少次,使用的都是同一個記憶體空間
模塊的導入,手寫的單例模式
實例化對象時發生的事:
創建對象,並開闢對象空間 __ next__
自動執行 __ init方法,隱性的將對象地址傳給self
將對象屬性封裝到對象空間
2、上下文
(1)__ enter__
(2)__ exit__
class my_open:
def __init__(self,file,mode="r",encoding="utf-8"):
self.file = file
self.mode = mode
self.encoding = encoding
def __enter__(self):
self.f = open(self.file,self.mode,encoding=self.encoding)
return self.f
def __exit__(self, exc_type, exc_val, exc_tb):
print(exc_type,exc_val,exc_tb) # 沒有錯誤時就是None
self.f.close()
with my_open("a.txt") as ffff:
for i in ffff:
print(i)
print(ffff.read(1111))
print(ffff.read())