搜尋
首頁後端開發Python教學聊聊Python中常見魔法方法

聊聊Python中常見魔法方法

May 15, 2023 pm 10:34 PM
python程式碼魔法方法

什麼是魔法方法?

魔法方法(Magic Methods)是Python中的內建函數,一般以雙底線開頭和結尾,例如__init__、__del__等。之所以稱之為魔法方法,是因為這些方法會在進行特定的操作時會自動被呼叫。

在Python中,可以透過dir()方法來查看某個物件的所有方法和屬性,其中雙下劃線開頭和結尾的就是該物件的魔法方法。以字串物件為例:

>>> dir("hello")
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mo
d__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center',
'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'isl
ower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', '
rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate'
, 'upper', 'zfill']

可以看到字串物件有__add__方法,所以在Python中可以直接對字串物件使用" "操作,當Python辨識到" "操作時,就會呼叫該物件的__add__方法。有需要時我們可以在自己的類別中重寫__add__方法來完成自己想要的效果。

class A(object):
def __init__(self, str):
self.str = str


• def __add__(self, other):
• print ('overwrite add method')
• return self.str + "---" + other.str


>>>a1 = A("hello")
>>>a2 = A("world")
>>>print (a1 + a2)
>>>overwrite add method
>>>"hello---world"

我們重寫了__add__方法,當Python識別" "操作時,會自動呼叫重寫後的__add__方法。可以看到,魔法方法在類別或物件的某些事件出發後會自動執行,如果希望根據自己的程式自訂特殊功能的類,那麼就需要對這些方法進行重寫。使用魔法方法,我們可以非常方便地為類別添加特殊的功能。

常用的魔法方法

1.建構與初始化

__new__、__init__ 這兩個魔法方法常用於對類別的初始化操作。上面我們建立a1 = A("hello")時,但首先呼叫的是__new__;初始化一個類別分為兩個步驟:    

  • a.呼叫該類別的new方法,傳回該類別的實例物件 
  • b.呼叫該類別的init方法,對實例物件進行初始化

__new__(cls, *args, **kwargs)至少需要一個cls參數,代表傳入的類別。後面兩個參數傳遞給__init__。在__new__可以決定是否繼續呼叫__init__方法,只有當__new__傳回了目前類別cls的實例,才會接著呼叫__init__。結合__new__方法的特性,我們可以透過重寫__new__方法實現Python的單例模式:

class Singleton(object):
def __init__(self):
print("__init__")

• def __new__(cls, *args, **kwargs):
• print("__new__")
• if not hasattr(Singleton, "_instance"):
• print("创建新实例")
• Singleton._instance = object.__new__(cls)
• return Singleton._instance

>>> obj1 = Singleton()
>>> __new__
>>> 创建新实例
>>> __init__
>>> obj2 = Singleton()
>>> __new__
>>> __init__
>>> print(obj1, obj2)
>>> (<__main__.Singleton object at 0x0000000003599748>, <__main__.Singleton object at 0x0000000003599748>)

可以看到雖然創建了兩個對象,但兩個對象的地址相同。

2.控制屬性存取這類魔法

方法主要對物件的屬性進行存取、定義、修改時起作用。主要有:

  • __getattr__(self, name): 定義當使用者試圖取得一個屬性時的行為。
  • __getattribute__(self, name):定義當該類別的屬性被存取時的行為(先呼叫該方法,查看是否存在該屬性,若不存在,接著去呼叫getattr)。
  • __setattr__(self, name, value):定義當一個屬性被設定時的行為。

當初始化屬性時如self.a=a時或修改實例屬性如ins.a=1時本質時調用魔法方法self.__setattr__(name,values);當實例存取某個屬性如ins.a本質是呼叫魔法方法a.__getattr__(name)

3.容器類別操作

有一些方法可以讓我們自己定義自己的容器,就像Python內建的List,Tuple,Dict等;容器分為可變容器和不可變容器。

如果自訂一個不可變容器的話,只能定義__len__和__getitem__;定義一個可變容器除了不可變容器的所有魔法方法,還需要定義__setitem__和__delitem__;如果容器可迭代。還需要定義__iter__。

  • __len__(self):傳回容器的長度
  •  __getitem__(self,key):當需要執行self[key]的方式去呼叫容器中的對象,呼叫的是此方法   __setitem__(self,key,value):當需要執行self[key] = value時,呼叫的是該方法
  • __iter__(self):當容器可以執行for x in container:,或使用iter(container)時,需要定義該方法

下面舉一個例子,實作一個容器,該容器有List的一般功能,同時增加一些其它功能如訪問第一個元素,最後一個元素,記錄每個元素被存取的次數等。

class SpecialList(object):
def __init__(self, values=None):
self._index = 0
if values is None:
self.values = []
else:
self.values = values
self.count = {}.fromkeys(range(len(self.values)), 0)

def __len__(self):# 通过len(obj)访问容器长度
return len(self.values)

def __getitem__(self, key):# 通过obj[key]访问容器内的对象
self.count[key] += 1
return self.values[key]

def __setitem__(self, key, value):# 通过obj[key]=value去修改容器内的对象
self.values[key] = value

def __iter__(self):# 通过for 循环来遍历容器
return iter(self.values)

def __next__(self):
# 迭代的具体细节
# 如果__iter__返回时self 则必须实现此方法
if self._index >= len(self.values):
raise StopIteration()
value = self.values[self._index]
self._index += 1
return value

def append(self, value):
self.values.append(value)

def head(self):
# 获取第一个元素
return self.values[0]

def last(self):
# 获取最后一个元素
return self.values[-1]

 這類方法的使用場景主要在你需要定義一個滿足需求的容器類別資料結構時會用到,例如可以嘗試自訂實作樹結構、鍊錶等資料結構(在collections中均已有),或專案中需要客製化的一些容器類型。

總結

魔法方法在Python程式碼中能夠簡化程式碼,提高程式碼可讀性,在常見的Python第三方函式庫中可以看到很多對於魔法方法的運用。因此目前這篇文章僅是拋磚引玉,真正的使用需要在開源的優秀源碼中以及自身的工程實踐中不斷加深理解並合適應用。

#

以上是聊聊Python中常見魔法方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:51CTO.COM。如有侵權,請聯絡admin@php.cn刪除
Python的科學計算中如何使用陣列?Python的科學計算中如何使用陣列?Apr 25, 2025 am 12:28 AM

Arraysinpython,尤其是Vianumpy,ArecrucialInsCientificComputingfortheireftheireffertheireffertheirefferthe.1)Heasuedfornumerericalicerationalation,dataAnalysis和Machinelearning.2)Numpy'Simpy'Simpy'simplementIncressionSressirestrionsfasteroperoperoperationspasterationspasterationspasterationspasterationspasterationsthanpythonlists.3)inthanypythonlists.3)andAreseNableAblequick

您如何處理同一系統上的不同Python版本?您如何處理同一系統上的不同Python版本?Apr 25, 2025 am 12:24 AM

你可以通過使用pyenv、venv和Anaconda來管理不同的Python版本。 1)使用pyenv管理多個Python版本:安裝pyenv,設置全局和本地版本。 2)使用venv創建虛擬環境以隔離項目依賴。 3)使用Anaconda管理數據科學項目中的Python版本。 4)保留系統Python用於系統級任務。通過這些工具和策略,你可以有效地管理不同版本的Python,確保項目順利運行。

與標準Python陣列相比,使用Numpy數組的一些優點是什麼?與標準Python陣列相比,使用Numpy數組的一些優點是什麼?Apr 25, 2025 am 12:21 AM

numpyarrayshaveseveraladagesoverandastardandpythonarrays:1)基於基於duetoc的iMplation,2)2)他們的aremoremoremorymorymoremorymoremorymoremorymoremoremory,尤其是WithlargedAtasets和3)效率化,效率化,矢量化函數函數函數函數構成和穩定性構成和穩定性的操作,製造

陣列的同質性質如何影響性能?陣列的同質性質如何影響性能?Apr 25, 2025 am 12:13 AM

數組的同質性對性能的影響是雙重的:1)同質性允許編譯器優化內存訪問,提高性能;2)但限制了類型多樣性,可能導致效率低下。總之,選擇合適的數據結構至關重要。

編寫可執行python腳本的最佳實踐是什麼?編寫可執行python腳本的最佳實踐是什麼?Apr 25, 2025 am 12:11 AM

到CraftCraftExecutablePythcripts,lollow TheSebestPractices:1)Addashebangline(#!/usr/usr/bin/envpython3)tomakethescriptexecutable.2)setpermissionswithchmodwithchmod xyour_script.3)

Numpy數組與使用數組模塊創建的數組有何不同?Numpy數組與使用數組模塊創建的數組有何不同?Apr 24, 2025 pm 03:53 PM

numpyArraysareAreBetterFornumericalialoperations andmulti-demensionaldata,而learthearrayModuleSutableforbasic,內存效率段

Numpy數組的使用與使用Python中的數組模塊陣列相比如何?Numpy數組的使用與使用Python中的數組模塊陣列相比如何?Apr 24, 2025 pm 03:49 PM

numpyArraySareAreBetterForHeAvyNumericalComputing,而lelethearRayModulesiutable-usemoblemory-connerage-inderabledsswithSimpleDatateTypes.1)NumpyArsofferVerverVerverVerverVersAtility andPerformanceForlargedForlargedAtatasetSetsAtsAndAtasEndCompleXoper.2)

CTYPES模塊與Python中的數組有何關係?CTYPES模塊與Python中的數組有何關係?Apr 24, 2025 pm 03:45 PM

ctypesallowscreatingingangandmanipulatingc-stylarraysinpython.1)usectypestoInterfacewithClibrariesForperfermance.2)createc-stylec-stylec-stylarraysfornumericalcomputations.3)passarraystocfunctions foreforfunctionsforeffortions.however.however,However,HoweverofiousofmemoryManageManiverage,Pressiveo,Pressivero

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境