日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python 特殊成员和魔法方法

發布時間:2025/3/20 python 11 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python 特殊成员和魔法方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Python中有大量類似__doc__這種以雙下劃線開頭和結尾的特殊成員及“魔法方法”,它們有著非常重要的地位和作用,也是Python語言獨具特色的語法之一!

比如:

  • __init__ : 構造函數,在生成對象時調用
  • __del__ : 析構函數,釋放對象時使用
  • __repr__ : 打印,轉換
  • __setitem__ : 按照索引賦值
  • __getitem__: 按照索引獲取值
  • __len__: 獲得長度
  • __cmp__: 比較運算
  • __call__: 調用
  • __add__: 加運算
  • __sub__: 減運算
  • __mul__: 乘運算
  • __div__: 除運算
  • __mod__: 求余運算
  • __pow__: 冪

需要注意的是,這些成員里面有些是方法,調用時要加括號,有些是屬性,調用時不需要加括號(廢話!)。下面將一些常用的介紹一下,:

1. __doc__

說明性文檔和信息。Python自建,無需自定義。

class Foo:""" 描述類信息,可被自動收集 """def func(self):pass# 打印類的說明文檔 print(Foo.__doc__)

2. __init__()

實例化方法,通過類創建實例時,自動觸發執行。

''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:778463939 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' class Foo:def __init__(self, name):self.name = nameself.age = 18obj = Foo(jack') # 自動執行類中的 __init__ 方法

3.__module__和__class__

__module__ 表示當前操作的對象在屬于哪個模塊。

__class__表示當前操作的對象屬于哪個類。

這兩者也是Python內建,無需自定義。

class Foo:passobj = Foo() print(obj.__module__) print(obj.__class__)------------ 運行結果: __main__ <class '__main__.Foo'>

4. __del__()

析構方法,當對象在內存中被釋放時,自動觸發此方法。

注:此方法一般無須自定義,因為Python自帶內存分配和釋放機制,除非你需要在釋放的時候指定做一些動作。析構函數的調用是由解釋器在進行垃圾回收時自動觸發執行的。

''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:778463939 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' class Foo:def __del__(self):print("我被回收了!")obj = Foo()del obj

5.__call__()

如果為一個類編寫了該方法,那么在該類的實例后面加括號,可會調用這個方法。

注:構造方法的執行是由類加括號執行的,即:對象 = 類名(),而對于__call__() 方法,是由對象后加括號觸發的,即:對象() 或者 類()()

class Foo:def __init__(self):passdef __call__(self, *args, **kwargs):print('__call__')obj = Foo() # 執行 __init__ obj() # 執行 __call__

那么,怎么判斷一個對象是否可以被執行呢?能被執行的對象就是一個Callable對象,可以用Python內建的callable()函數進行測試,我們在前面的章節已經介紹過這個函數了。

>>> callable(Student()) True >>> callable(max) True >>> callable([1, 2, 3]) False >>> callable(None) False >>> callable('str') False >>> callable(int) True >>> callable(str) True

6. __dict__

列出類或對象中的所有成員!非常重要和有用的一個屬性,Python自建,無需用戶自己定義。

''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:778463939 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' class Province:country = 'China'def __init__(self, name, count):self.name = nameself.count = countdef func(self, *args, **kwargs):print'func'# 獲取類的成員 print(Province.__dict__)# 獲取 對象obj1 的成員 obj1 = Province('HeBei',10000) print(obj1.__dict__)# 獲取 對象obj2 的成員 obj2 = Province('HeNan', 3888) print(obj2.__dict__)

7. __str__()

如果一個類中定義了__str__()方法,那么在打印對象時,默認輸出該方法的返回值。這也是一個非常重要的方法,需要用戶自己定義。

下面的類,沒有定義__str__()方法,打印結果是:<__main__.Foo object at 0x000000000210A358>

class Foo:passobj = Foo() print(obj)

定義了__str__()方法后,打印結果是:‘jack’。

''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:778463939 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' class Foo:def __str__(self):return 'jack'obj = Foo() print(obj)

8、__getitem__()、__setitem__()、__delitem__()

取值、賦值、刪除這“三劍客”的套路,在Python中,我們已經見過很多次了,比如前面的@property裝飾器。

Python中,標識符后面加圓括號,通常代表執行或調用方法的意思。而在標識符后面加中括號[],通常代表取值的意思。Python設計了__getitem__()、__setitem__()、__delitem__()這三個特殊成員,用于執行與中括號有關的動作。它們分別表示取值、賦值、刪除數據。

也就是如下的操作:

a = 標識符[] :   執行__getitem__方法 標識符[] = a :   執行__setitem__方法 del 標識符[] :   執行__delitem__方法

如果有一個類同時定義了這三個魔法方法,那么這個類的實例的行為看起來就像一個字典一樣,如下例所示:

class Foo:def __getitem__(self, key):print('__getitem__',key)def __setitem__(self, key, value):print('__setitem__',key,value)def __delitem__(self, key):print('__delitem__',key)obj = Foo()result = obj['k1'] # 自動觸發執行 __getitem__ obj['k2'] = 'jack' # 自動觸發執行 __setitem__ del obj['k1'] # 自動觸發執行 __delitem__

9. __iter__()

這是迭代器方法!列表、字典、元組之所以可以進行for循環,是因為其內部定義了 iter()這個方法。如果用戶想讓自定義的類的對象可以被迭代,那么就需要在類中定義這個方法,并且讓該方法的返回值是一個可迭代的對象。當在代碼中利用for循環遍歷對象時,就會調用類的這個__iter__()方法。

普通的類:

''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:778463939 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' class Foo:passobj = Foo()for i in obj:print(i)# 報錯:TypeError: 'Foo' object is not iterable<br># 原因是Foo對象不可迭代

添加一個__iter__(),但什么都不返回:

class Foo:def __iter__(self):passobj = Foo()for i in obj:print(i)# 報錯:TypeError: iter() returned non-iterator of type 'NoneType'#原因是 __iter__方法沒有返回一個可迭代的對象

返回一個個迭代對象:

class Foo:def __init__(self, sq):self.sq = sqdef __iter__(self):return iter(self.sq)obj = Foo([11,22,33,44])for i in obj:print(i)# 這下沒問題了!

最好的方法是使用生成器:

''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:778463939 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' class Foo:def __init__(self):passdef __iter__(self):yield 1yield 2yield 3obj = Foo() for i in obj:print(i)

10、__len__()

在Python中,如果你調用內置的len()函數試圖獲取一個對象的長度,在后臺,其實是去調用該對象的__len__()方法,所以,下面的代碼是等價的:

>>> len('ABC') 3 >>> 'ABC'.__len__() 3

Python的list、dict、str等內置數據類型都實現了該方法,但是你自定義的類要實現len方法需要好好設計。
11. __repr__()

這個方法的作用和__str__()很像,兩者的區別是__str__()返回用戶看到的字符串,而__repr__()返回程序開發者看到的字符串,也就是說,__repr__()是為調試服務的。通常兩者代碼一樣。

class Foo:def __init__(self, name):self.name = namedef __str__(self):return "this is %s" % self.name__repr__ = __str__

12. __add__: 加運算 __sub__: 減運算 __mul__: 乘運算 __div__: 除運算__mod__: 求余運算 __pow__: 冪運算

這些都是算術運算方法,需要你自己為類設計具體運算代碼。有些Python內置數據類型,比如int就帶有這些方法。Python支持運算符的重載,也就是重寫。

''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:778463939 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' class Vector:def __init__(self, a, b):self.a = aself.b = bdef __str__(self):return 'Vector (%d, %d)' % (self.a, self.b)def __add__(self,other):return Vector(self.a + other.a, self.b + other.b)v1 = Vector(2,10) v2 = Vector(5,-2) print (v1 + v2)

13. __author__

__author__代表作者信息!類似的特殊成員還有很多,就不羅列了。

#!/usr/bin/env python # -*- coding:utf-8 -*-""" a test module """ __author__ = "Jack"def show():print(__author__)show()

14. __slots__

Python作為一種動態語言,可以在類定義完成和實例化后,給類或者對象繼續添加隨意個數或者任意類型的變量或方法,這是動態語言的特性。例如:

def print_doc(self):print("haha")class Foo:passobj1 = Foo() obj2 = Foo() # 動態添加實例變量 obj1.name = "jack" obj2.age = 18 # 動態的給類添加實例方法 Foo.show = print_doc obj1.show() obj2.show()

但是!如果我想限制實例可以添加的變量怎么辦?可以使__slots__限制實例的變量,比如,只允許Foo的實例添加name和age屬性。

''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:778463939 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' def print_doc(self):print("haha")class Foo:__slots__ = ("name", "age")passobj1 = Foo() obj2 = Foo() # 動態添加實例變量 obj1.name = "jack" obj2.age = 18 obj1.sex = "male" # 這一句會彈出錯誤 # 但是無法限制給類添加方法 Foo.show = print_doc obj1.show() obj2.show()

由于’sex’不在__slots__的列表中,所以不能綁定sex屬性,試圖綁定sex將得到AttributeError的錯誤。

Traceback (most recent call last):File "F:/Python/pycharm/201705/1.py", line 14, in <module>obj1.sex = "male" AttributeError: 'Foo' object has no attribute 'sex'

需要提醒的是,__slots__定義的屬性僅對當前類的實例起作用,對繼承了它的子類是不起作用的。想想也是這個道理,如果你繼承一個父類,卻莫名其妙發現有些變量無法定義,那不是大問題么?如果非要子類也被限制,除非在子類中也定義__slots__,這樣,子類實例允許定義的屬性就是自身的__slots__加上父類的__slots__。

Python的特殊成員和“魔法方法”還有很多,需要大家在平時使用和學習的過程中不斷積累和總結使用經驗。

總結

以上是生活随笔為你收集整理的Python 特殊成员和魔法方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。