python神秘的魔法函數_python魔法函數

一、參考

二、構造和初始化

2.1 __new__

在對象實例化過程中最先調用的方法是__new__, 該方法接收參數為類,然后將其他參數,傳遞給__init__, 該魔法函數比較少見,可以使用其,創建單例類; __new__方法是一個類方法,需要攜帶的第一個參數是類

class T1(object):

_instances = {}

def __new__(class_, *args, **kwargs):

if class_ not in class_._instances:

class_._instances[class_] = super(T1, class_).__new__(class_, *args, **kwargs)

return class_._instances[class_]

def __init__(self, *args, **kwargs):

pass

2.2 __init__

__init__是一個實例方法,用于將構造的實例初始化,在類定義中十分常見

2.3 __del__

類比于C++, __new__和__init__可以當作類的構造函數,__del__充當類的析構函數,該函數在垃圾回收時候調用,而不是在del object時候觸發,可以用于添加套接字或者文件的close()邏輯,但是使用需要小心,實際幾乎不使用該方法

from os.path import join

class FileObject:

'''Wrapper for file objects to make sure the file gets closed on deletion.'''

def __init__(self, filepath='~', filename='sample.txt'):

# open a file filename in filepath in read and write mode

self.file = open(join(filepath, filename), 'r+')

def __del__(self):

self.file.close()

del self.file

三、重定義運算符

四、獲取類表示信息

4.1 __str__

__str__(self)

自定義對類調用str()方法時候的行為

4.2 __repr__

__repr__(self)

定義對類的實例調用repr()時候的行為,str()和repr()的不同之處是:目標受眾的不同,repr()的目的是生成主要是機器可讀的輸出,許多情況下,可能輸出為python代碼, 而str()一般輸出為人類可讀的信息

4.3 __unicode__

__unicode__(self)

定義對類實例執行unicode()方法時候的行為,其返回unicode字符串,如果只定義了unicode(),使用str()會報錯,所以需要同事定義兩個函數

4.4 __format__

__format__(self, formatstr)

定義在新樣式字符串格式中使用類實例時候的行為

4.5 __hash__

__hash__(self)

當調用hash()函數時候定義行為,通常用于字典中的key的快速比較是否相同,通常也需要實現__eq__, 遵循下面的規則,

a == b 實際為 hash(a) == hash(b)

4.6 __nonzero__

__nonzero__(self)

定義對類的實例調用bool()時候的行為,返回值為True或者False,取決于具體的類

4.7 __dir__

__dir__(self)

定義對類的實例調用dir()函數時候的行為,返回值是用戶的屬性列表,通常,實現dir()函數是不必要的,但是,如果重新定義了__getattr__或者__getattribute__或者其他動態生成屬性,則其對于交互式使用類非常重要

4.8 __sizeof__

__sizeof__(self)

定義對類實例調用sys.getsizeof()函數時候的行為,返回值為對象的大小(字節為單位),通常對于C擴展實現的Python類有作用

五、控制屬性訪問

如果與其他語言比較(例如: Java),Python中好像沒有真正的封裝,例如,沒有辦法通過公共函數getter和setter定義私有屬性,這是事實。

Python通過下列的魔法函數實現屬性的封裝,而不是使用顯式的修飾符

5.1 __getattr__

__getattr__(self, name)

可以定義當用戶試圖訪問一個不存在的屬性時候的行為,這對于捕獲或者重定向常見的拼寫錯誤、引發警告等非常有用,只有當訪問不存在的屬性時候才會調用該方法,因此它不是真正的封裝解決方案

5.2 __setattr__

__setattr__(self, name, value)

與__getattr__不相同,__setattr__是一種封裝解決方案,允許定義分配屬性值的行為,如果該屬性值已經存在,則會覆蓋,由此可以自定義屬性值的賦值規則

def __setattr__(self, name, value):

self.name = value

# since every time an attribute is assigned, __setattr__() is called, this

# is recursion.

# so this really means self.__setattr__('name', value). Since the method

# keeps calling itself, the recursion goes on forever causing a crash

由上,代碼self.name = value會調用__setattr__內置函數,所以會導致循環無限遞歸,正確的定義方式為

def __setattr__(self, name, value):

self.__dict__[name] = value # assigning to the dict of names in the class

# define custom behavior here

5.3 __delattr__

__delattr__(self, name)

與__setattr__相同,但是作用是刪除屬性而不是設置屬性,為了防止無限遞歸,還需要采取與__setattr__相同的預防措施(在__delattr__的實現中調用del self.name將導致無限遞歸)

5.4 __getattribute__

__getattribute__(self, name)

不建議使用該函數,因為極少情況下可以不產生bug正確使用。

每次獲取屬性時候,都會調用該函數

5.5 總結

Python的魔法方法非常重要且強大,如果任意使用可能會帶來破壞,因此,在已經充分了解了自定義屬性訪問之前,不要隨意使用該魔法方法,事實上,魔法方法往往過于強大和反直覺,它存在的原因是:通過它,可以自由的做任何想做的事情,但是如果不充分熟悉,使用將會非常困難。

class AccessCounter(object):

'''A class that contains a value and implements an access counter.

The counter increments each time the value is changed.'''

def __init__(self, val):

super(AccessCounter, self).__setattr__('counter', 0)

super(AccessCounter, self).__setattr__('value', val)

def __setattr__(self, name, value):

if name == 'value':

super(AccessCounter, self).__setattr__('counter', self.counter + 1)

# Make this unconditional.

# If you want to prevent other attributes to be set, raise AttributeError(name)

super(AccessCounter, self).__setattr__(name, value)

def __delattr__(self, name):

if name == 'value':

super(AccessCounter, self).__setattr__('counter', self.counter + 1)

super(AccessCounter, self).__delattr__(name)

六、自定義序列

七、反射

八、可調用對象

在python中,函數是第一類對象,這意味著它們可以被傳遞給函數和方法,好像其他第一類對象一樣(數值、字符串等),而這是一個非常強大的功能。

通過魔法函數__call__,可以使得實例也表現的像函數一樣,以便可以調用實例,可以將實例作為參數在函數調用中傳遞。

8.1 __call__

__call__(self, [args...])

允許將實例進行函數調用,如下,實際作用為e(5,6)實際為調用e.__call__(5,6)

在經常需要修改實例的狀態的場景下,使用__call__調用實例,修改實例狀態是一種十分直觀且優雅的方式

class Entity(object):

'''Class to represent an entity. Callable to update the entity's position.'''

def __init__(self, size, x, y):

self.x, self.y = x, y

self.size = size

def __call__(self, x, y):

'''Change the position of the entity.'''

self.x, self.y = x, y

if __name__ == '__main__':

e = Entity(size=10, x=1, y=2)

print(e)

e(5, 6)

print(e)

九、上下文管理

十、抽象基類

十一、描述符對象

十二、復制

十三、序列化對象

十四、結論

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/533669.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/533669.shtml
英文地址,請注明出處:http://en.pswp.cn/news/533669.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python掃雷 廣度優先_廣度優先搜索(BFS)解題總結

定義 廣度優先搜索算法(Breadth-First-Search),是一種圖形搜索算法。 簡單的說,BFS是從根節點開始,沿著樹(圖)的寬度遍歷樹(圖)的節點。 如果所有節點均被訪問,則算法中止。 BFS同樣屬于盲目搜索。 一般用隊…

python默認參數陷阱_python默認參數陷阱

0|1陷阱?學過函數的人一定聽說過函數的默認參數,關于函數的默認參數,請看以下的例子:def extendList(val, lst[]):lst.append(val)return lstlist1 extendList(10)list2 extendList(123, [])print(list1 %s % list1)print(list…

python裁剪圖片并保存_python – 如何從圖像中剪切輪廓并將其保存到新文件中

大家好,這是我的第一個問題所以請保持溫和.我有一個計算機視覺領域的項目,我是新的,我會很感激一些幫助.我有一個pcb的圖像,我的(首先)任務是從背景中切斷電路板并將其保存到新文件.如果結果只是沒有灰色背景的普通pcb,那就沒問題了. 我到目前為止嘗試的是,首先使用閾值將圖像轉…

opencv如何把一個矩陣不同列分離開_學習OPEN_CV

OpenCv中文論壇精華地址http://www.opencv.org.cn/index.php/User:Ollydbg23http://sivp.sourceforge.net/(sivp)一、基礎操作1. 數據類型 數據結構了解圖像相關:cvArr cvMat IplImage數據數組的維數, 與數據的通道數 見P46 (76)2. 常見的矩陣操作熟悉3…

python文件合并_用Python 將兩個文件的內容合并成一個新的文件.

一個文件的內容是:IntroductiontoProgramming,NetworkingFundamentals,InternetworkingTechnologies,PlatformTechnologies,InformationTechnologyforUsers,ComputerForensics,Enterpr... 一個文件的內容是: Introduction to Programming, Networking Fundamentals, Internetwo…

flash代碼_Flash如何對制作文件進行優化

對FLASH進行優化分為兩方面,一方面是代碼上的優化,主要是通過優化提高FLASH性能,降低CPU占用和內存使用。另一方面是資源的優化,這方面的優化是為了減小編譯后的文件大小以及制作文件的大小,因為如果不進行相應的優化&…

潛流式濕地計算_人工濕地計算書

人工濕地計算書1、尾水提升泵房集水池基本參數集水池設計規模為30000m3/d,約折合1250m3/h,按水力停留時間HRT為0.25 h計,集水井有效容積應為312.5 m3,考慮到與污水廠原有排污管道相契合,集水設計尺寸為:LBH…

deepin系統轉為windows_windows系統下安裝深度系統deepin

前期準備DiskGenius(用來擴展分區)deepin-20-amd64.iso(深度系統鏡像文件)相關文件下載首先下載安裝時要用的工具,分別為:DiskGenius , UltraISODiskGenius是一款磁盤工具,創建系統分區。UltraISO是用來打開系統光盤鏡像文件工具。Win8/8.1/10無需下載Ul…

c3等待加載樣式 vue_Vue.js__簡易加載等待動畫

Vue.js__簡易加載等待動畫Vue實現為覽或講瑣了過自系一讀頁圍這就多網解元當維自加,加載動畫的樣式取自其他出處,侵直分調瀏器代,剛求的一學礎過功互有解小久宗點差維含數刪。將Vue屬性覽或講瑣了過自系一讀頁圍這就多網解元當維和方法復制到…

軟件開發模型_QT開發(二十三)——軟件開發流程

一、軟件開發流程簡介軟件開發流程是通過一系列步驟保證軟件產品的順利完成,是軟件產品在生命周期內的管理學。軟件開發流程的本質是軟件開發流程與具體技術無關,是開發團隊必須遵守開的規則。二、常見軟件開發流程模型常見的軟件開發流程模型包括即興模…

python循環語句for計數_Bash For循環(遞增計數)與for循環用法詳解

先來看for循環的例子&#xff1a;用Bash Shell的for循環&#xff0c;每次遞增數是500。復制代碼 代碼示例:#!/bin/bash##每次遞增的數ADD_NUM500#遞增1的話取消下行注釋&#xff0c;并相應的注釋另一句for的開頭的#for ((i1;i<29500;i))#遞增定義的數for ((i1;i<29500;i$…

python3.6.2用pyinstaller3.4報錯_OceanBase 2.2 版本體驗:用 BenchmarkSQL 跑 TPC-C

OB君&#xff1a;好消息&#xff01;「 OceanBase 2.2 版本 」正式上線官網啦&#xff01;&#xff08;點擊閱讀原文即可直接下載&#xff09;OceanBase 2.2版本是成功支撐2019年天貓雙11大促的穩定版本&#xff0c;同時也是用于TPC-C測試且榮登TPC-C性能榜首的版本。我們將在接…

hive窗口函數_Hive sql窗口函數源碼分析

在了解了窗口函數實現原理 spark、hive中窗口函數實現原理復盤 和 sparksql比hivesql優化的點(窗口函數)之后&#xff0c;今天又擼了一遍hive sql 中窗口函數的源碼實現&#xff0c;寫個筆記記錄一下。簡單來說&#xff0c;窗口查詢有兩個步驟&#xff1a;將記錄分割成多個分區…

容大打印機ip修改工具_M1芯片版Mac無法連接打印機怎么辦?

文末有優惠券在入手了M1芯片版MacBook Pro后&#xff0c;昨天我打算連接一下實驗室的打印機。這個打印機的型號是HP LaserJet Professional M1213nf MFP&#xff0c;在同一個局域網內通過搜索IP即可連接。在我的舊設備2015款MacBook Air上&#xff0c;很輕松就連接了打印機。可…

語音對講軟件_三款語音轉文字工具,語音輸入,高效轉換,準確率高

關于語音轉文字的軟件我在之前講了很多&#xff0c;有些人聽了也用了&#xff0c;效果不錯&#xff0c;有些人看了就忘了&#xff0c;主要是不知道用它干嘛&#xff0c;其實語音轉文字的軟件主要功能就是為了讓自己在寫作的時候可以減少時間&#xff0c;提高效率&#xff0c;其…

linux中如何復制文件并重命名_linux復制重命名 linux復制一個文件并重命名

linux下怎么復制一個文件到另外一個目錄并且重命名&#xff1f;使用Linux的CP命令復制一個文件&#xff0c;并指定一個新的文件名作為目標文件參數&#xff0c;實現復制文件時重命名文件的功能。例如&#xff0c;下面的命令將/root/fileaaa分配給/home目錄并將其重命名為filebb…

python程序員搞笑段子_程序員的爆笑漫畫和段子

Hi&#xff01;大家好呀&#xff01;我是你們幽默的喵哥&#xff01;每次推送&#xff0c;都是給大家推薦實用的項目或者技術&#xff0c;都比較枯燥。今天&#xff0c;喵哥就來給大家搞個有趣且幽默的。在程序員圈子中&#xff0c;我們也是有自己的職業文化的。比如&#xff0…

野火stm32呼吸燈程序_說一說STM32啟動過程

STM32上電后是怎么啟動的&#xff1f;main函數之前單片機都做了些什么&#xff1f;帶著這些疑問我們開始進入游戲。。。。。首先&#xff0c;開局一張圖&#xff0c;過程全靠編&#xff0c;如有說錯的地方望能指正啟動大致流程1- 上電啟動或者硬件復位2- 單片機從0x00地址開始執…

linuxpython升級3.5_linux升級python3.5到3.6

在ubuntu里&#xff0c;zlib叫zlib1g&#xff0c;相應的zlib-devel叫zlib1g.dev。默認的安裝源里沒有zlib1g.dev。要在packages.ubuntu.com上找。$sudo apt-get install ruby然后再裝zlib1g-dev就可以了$sudo apt-get install zlib1g-dev1. 安裝必備的軟件包centos: yum -y gro…

apache啟動失敗_請檢查相關配置.√mysql5.1已啟動._1、Apache啟動失敗,請檢查相關配置-百度經驗...

前幾天電腦系統崩潰了,后邊到服務中心重新恢復了系統,但是回來使用APMServ 5.2.6發現:1、Apache啟動失敗,請檢查相關配置。√MySQL5.1已啟動。系統的各種服務我都檢查過了,都是正常開啟的,百思不得其解,后邊在百度上搜索一篇文章有個例子照做了以后結果成功了。---------------…