python 魔法方法常用_Python 常用魔法方法(下)
Python 常用魔法方法(下)
回顧
魔法方法是 Python 內(nèi)置方法, 不需要我們手動調(diào)用, 它存在的目的是給 解釋器 調(diào)用的. 比如我們在寫 "1 + 1 " 的時候, 這個 "+ " 就會自動調(diào)用內(nèi)置的魔法方法 "__ add__" . 幾乎每個魔法方法, 都有一個對應(yīng)的內(nèi)置函數(shù)或運(yùn)算符. 當(dāng)我們使用這些方法去操作數(shù)據(jù)時, 解釋器會自動調(diào)用這些對應(yīng)的魔法方法. 也可以理解為, 重寫內(nèi)置函數(shù), 如果改變的話.
具體的魔法方法等. 可以去看 內(nèi)置的 builtins.py 這個接口文檔.
內(nèi)置函數(shù)對應(yīng)魔法方法: 如 next() 對應(yīng) __ next __ , 類名() 對應(yīng) __ call __ 等這樣的映射關(guān)系 ....
這一塊的上篇呢, 還主要分享 type 類和 object 類來闡明 "萬物皆對象". object 類是所有類的 基類. 而 type 類則用來判斷某個實例對象所屬的 "父類" 是誰, 類似父類,不絕對準(zhǔn)確, 用來理解. 比如, 123 是 "int" class; "123" 是 "str" class; "str" 的 type 就是 type; object 的類型也是 type, 但 object 是 type 類的基類.
上篇引出 type 類, 當(dāng)時用了一些哲學(xué)概念上的, "一, 二, 三" 來比喻, 仔細(xì)一想, 表述不太對, "元類" 的概念沒說
元類 (metaclass): 如果是 type類是用來 靜態(tài)創(chuàng)建類, 則 metaclass 是用來創(chuàng)建類的行為.
這一塊先不談了, 不太敢妄言, 待之后仔細(xì)查完資料在總結(jié)吧.
本篇還是繼續(xù)介紹常用的魔法方法. 上篇主要對 __ new __, __ __ init __, __ __ call __ , __ str __, __ __ del __ 初步認(rèn)識, 并應(yīng)用場景簡單舉了例子. go on...
補(bǔ): 關(guān)于 __ new __:
通常與 __ init __, 被稱為 "構(gòu)造函數(shù)". _____ del __ 被稱為 "析構(gòu)函數(shù)".
我目前用的的例子, 就只用 "單例" 用到.
new 方法還涉及到 metaclass 的知識, 平時也不太用得到, 姑且先不涉及了.
用于繼承一個不可邊類型對象類 (tuple, int, str...) 的構(gòu)造器, 當(dāng)一個實例被創(chuàng)建時的初始化方法.
魔法方法總結(jié)
常用
__ new__ (cls, ....) 實例化所調(diào)用, 返回一個實例對象,(若無, 則不會調(diào) __ init __ 在單例場景中時有用過.
__ init __ (self,...) 類實例化時, 的初始化值設(shè)置.
__ del __ (self) 也稱為析構(gòu)器. 當(dāng)一個實例被 del 的時候會被觸發(fā).
__ call __(self, ...) 將類實例對象, "裝飾" 為像函數(shù)一行可調(diào)用, 即 obj(*args.), 在 裝飾器 有用到.
__ str __ (self) 描述對象信息, 在 print(obj) 時被觸發(fā).
__ len __ (self) 在使用 len() 時被調(diào)用.
__ repr __ (self) 在使用 repr() 時被調(diào)用.
repr(), 返回一個對象的 string 格式, 就是在外面套一個 "", 跟 eval() 函數(shù)像是其逆.
# repr(obj) -> str
# eval(str) -> obj
>>> repr(123)
'123'
>>> repr([1,2,"cj", [1,[2]]])
"[1, 2, 'cj', [1, [2]]]"
t = repr({'a':123, 'b':{"c":4}})
>>> t
"{'a': 123, 'b': {'c': 4}}"
>>> eval(t)
{'a': 123, 'b': {'c': 4}}
__ bytes __ (self) 在使用 bytes() 時被調(diào)用.
__ hash __ (self) 在使用 hash() 時被調(diào)用. 返回可哈希對象的數(shù)值, 傳不可哈希(如list) 則報錯
__ bool __ (self) 在 bool() 時被調(diào)用.
__ format __ (self,...) 在使用 format() 被調(diào)用. 不過我更多使用 f"{變量名} hello" 這樣的語法多一點.
....
屬性的
__ getattr __(self, item) 試圖獲取一個不存在屬性的行為. 曾用來, 用來做異常判斷.
__ getattribute __(self, item) 該類屬性被訪問時的行為. 跟 getattr 其實不太好搭配.
__ setattr __(self, key, value) 當(dāng)一個屬性被設(shè)置時的行為, obj.name = "youge"
__ delattr __(self, item) 屬性被刪除時的行為.
__ dir __(self) 定義當(dāng) dir() 被調(diào)用時的行為
__ get__ (self, instance, owner) 定義當(dāng)描述符的值被取得時的行為
__ set__ (self, instance, value) 定義當(dāng)描述符的值被改變時的行為
__ delete __(self, instance) 定義當(dāng)描述符的值被刪除時的行為
...
比較的
__ lt__ (self, other) 小于號的行為:x < y 調(diào)用 x.__ lt __(y)
__ le__ (self, other) 小于等于號的行為:x <= y 調(diào)用 x.__ le__(y)
__ eq__ (self, other) 等于號的行為:x == y 調(diào)用 x.__ eq__(y)
__ ne__ (self, other) 不等號的行為:x != y 調(diào)用 x.__ ne__(y)
__ gt __ (self, other) 大于號的行為:x > y 調(diào)用 x.__ gt__(y)
__ ge __ (self, other) 大于等于號的行為:x >= y 調(diào)用 x.__ ge__(y)
...
算數(shù)的
__ add__(self, other) 定義加法的行為:+
__ sub__(self, other) 定義減法的行為:-
__ mul__(self, other) 定義乘法的行為:*
__ truediv__(self, other) 定義真除法的行為:/
__ floordiv__(self, other) 定義整數(shù)除法的行為://
__ mod__(self, other) 定義取模算法的行為:%
__ divmod__(self, other) 定義當(dāng)被 divmod() 調(diào)用時的行為
__ pow__(self, other[, modulo]) 定義當(dāng)被 power() 調(diào)用或 ** 運(yùn)算時的行為
... 還有什么 位運(yùn)算, 逆運(yùn)算, 增量賦值 .. 各種計算符號, 都是一個個的魔法方法, 即都是可以改寫的.
這些有啥用呢, 舉個算數(shù)的, 通過重寫, 可以自定義 運(yùn)算符, 比如 1 +1 = 3 是可以的
# 重寫 "+" 這個運(yùn)算符, 即重寫 __add__ 這個方法
class Num:
def __init__(self, value):
self.value = value
def __add__(self, other):
print(self.value + other + 1)
if __name__ == '__main__':
one = Num(1)
one + 1
# output
3
類型轉(zhuǎn)換
__ complex__(self) 定義當(dāng)被 complex() 調(diào)用時的行為(需要返回恰當(dāng)?shù)闹?#xff09;
__ int__(self) 定義當(dāng)被 int() 調(diào)用時的行為
__ float__(self) 定義當(dāng)被 float() 調(diào)用時的行為
__ round__(self[, n]) 定義當(dāng)被 round() 調(diào)用時的行為
__ index__(self)
這一塊了解就行, 建議不要亂改, 是關(guān)聯(lián)的, 比如 index 被重寫, 那 int 也有重寫, 而且返回值也是要相同的.
上下文管理
__ enter__ (self)
定義當(dāng)使用 with 語句時的初始化行為
__ enter__ 的返回值被 with 語句的目標(biāo)或者 as 后的名字綁定
__ exit__ (self, exc_type, exc_value, traceback)
定義當(dāng)一個代碼塊被執(zhí)行或者終止后上下文管理器應(yīng)該做什么
一般被用來處理異常,清除工作或者做一些代碼塊執(zhí)行完畢之后的日常工作
容器類型
__ len__(self) 定義當(dāng)被 len() 調(diào)用時的行為(返回容器中元素的個數(shù))
__ getitem__(self, key) 定義獲取容器中指定元素的行為,相當(dāng)于 self[key]
__ setitem__(self, key, value) 定義設(shè)置容器中指定元素的行為,相當(dāng)于 self[key] = value
__ delitem__(self, key) 定義刪除容器中指定元素的行為,相當(dāng)于 del self[key]
__ iter__(self) 定義當(dāng)?shù)萜髦械脑氐男袨?/p>
__ reversed__(self) 定義當(dāng)被 reversed() 調(diào)用時的行為
__ contains__(self, item) 定義當(dāng)使用成員測試運(yùn)算符(in 或 not in)時的行為
容器這個概念, 很直觀有抽象, 是有點矛盾, 但 非常重要.
這里舉個 迭代器 的栗子, 后面會單獨(dú)來講, 這里引入一波, 迭代器: 實現(xiàn)了 __ iter __ , __ next __ 的類 (容器)
class Iterator:
"""迭代器, 以list 作為底層結(jié)構(gòu)"""
def __init__(self, lst):
self.lst = lst
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index < len(self.lst):
# get current value
value = self.lst[self.index]
self.index += 1
else:
raise StopIteration
return value
# __next__ 為了能與 for 對應(yīng)上
# __iter__ 迭代后返回自身
小結(jié)
每一個魔法方法, 幾乎都跟咱用的 內(nèi)置函數(shù)是有映射關(guān)系的
可以通過重寫魔法方法來適應(yīng)業(yè)務(wù), 如運(yùn)算符重載, 類屬性判斷, 異常檢測等.
還是在于設(shè)計類這方面會很有用的.
本篇的目的是大致了解魔法方法, 留印象為主, 具體用啥, 再進(jìn)行百度即可.而上篇呢重點是舉了幾個常用來重寫魔法方法的應(yīng)用場景, 當(dāng)然也是我自己經(jīng)驗有限, 目前只用到的非常少吧.
總結(jié)
以上是生活随笔為你收集整理的python 魔法方法常用_Python 常用魔法方法(下)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 编译 SDK
- 下一篇: python注销代码_django用户注