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

歡迎訪問 生活随笔!

生活随笔

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

python

Python面向对象-特殊成员

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

我們知道類中有字段、方法和屬性三大類成員,并且成員名前如果有兩個下劃線,則表示該成員是私有成員,私有成員只能由類內部調用。

Python的類成員還存在著一些具有特殊含義的成員,其中有一些比較重要的,我們一一來看:

(1) __init__

構造方法,通過類創建對象時,自動觸發執行。

1 class Student(object): 2 def __init__(self, name): 3 self.name = name 4 5 ...

(2) __del__

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

注:此方法一般無須定義,因為Python是一門高級語言,程序員在使用時無需關心內存的分配和釋放,因為此工作都是交給Python解釋器來執行,所以,析構函數的調用是由解釋器在進行垃圾回收時自動觸發執行的

1 class Student(object): 2 ... 3 4 def __del__(self): 5 pass

(3)?__call__

我們已經知道了類名后面加()是調用__init__方法,那對象后面加()呢?請看下面的代碼:

1 class Student(object): 2 def __init__(self, name): 3 self.name = name 4 5 def __call__(self): 6 print(self.name) 7 8 ... 9 10 mike = Student("Mike") 11 mike()

程序輸出是:?Mike?,我們可以看到對象()會調用__call__方法,我們可以通過callable()函數判斷對象是否可以調用

(4)?__dict__

有沒有辦法獲取對象里所有普通字段及其值呢?Python為我們提供了__dict__:

1 class Student(object): 2 Nation = "China" 3 4 def __init__(self, name): 5 self.name = name 6 self.score = 0 7 8 ... 9 10 mike = Student("Mike") 11 print(mike.__dict__)

程序輸出:?{'score': 0, 'name': 'Mike'}?,對于靜態字段Nation = "China",__dict__內并不包含

(5) __str__ , __repr__?

對于一個對象,我們對其使用print時,默認程序輸出的是對象的內存地址:

1 class Student(object): 2 def __init__(self, name): 3 self.name = name 4 self.score = 0 5 6 ... 7 8 mike = Student("Mike") 9 print(mike)

程序輸出:?<__main__.Student object at 0x0050F7B0>?

怎么才能打印得好看呢?只需要定義好__str__()方法,返回一個好看的字符串就可以了:

1 class Student(object): 2 def __init__(self, name): 3 self.name = name 4 self.score = 0 5 6 def __str__(self): 7 return self.name 8 ... 9 10 mike = Student("Mike") 11 print(mike)

程序輸出就是__str__方法的返回值:?Mike?

如果我們把上面的代碼在idle里運行,并敲下mike時(>>>mike),打印出來的還是對象的地址,

這是因為直接顯示變量調用的不是__str__(),而是__repr__(),兩者的區別是__str__()返回用戶看到的字符串,而__repr__()返回程序開發者看到的字符串,也就是說,__repr__()是為調試服務的。

解決辦法是再定義一個__repr__()。但是通常__str__()和__repr__()代碼都是一樣的,所以,有個偷懶的寫法:

1 class Student(object): 2 def __init__(self, name): 3 self.name = name 4 self.score = 0 5 6 def __str__(self): 7 return self.name 8 __repr__ = __str__

(6)?__iter__

如果一個類想被用于for ... in循環,類似list或tuple那樣,就必須實現一個__iter__()方法,該方法返回一個迭代對象,然后,Python的for循環就會不斷調用該迭代對象的__next__()方法拿到循環的下一個值,直到遇到StopIteration錯誤時退出循環。

我們以斐波那契數列為例,寫一個Fib類,可以作用于for循環:

1 class Fib(object): 2 def __init__(self, maximum): 3 self.a = 0 4 self.b = 1 # 初始化兩個計數器a,b 5 self.maximum = maximum # 定義停止循環的條件 6 7 def __iter__(self): 8 return self # 實例本身就是迭代對象,故返回自己 9 10 # Python的for循環就會不斷調用該迭代對象的__next__()方法拿到循環的下一個值,直到遇到 11 # StopIteration錯誤時退出循環 12 def __next__(self): 13 self.a, self.b = self.b, self.a + self.b 14 if self.a > self.maximum: 15 raise StopIteration() 16 return self.a 17 18 for item in Fab(100): 19 print(item)

(7)?__getitem__、__setitem__、__delitem__

上面的Fib類的對象雖然能作用于for循環,看起來和list有點像,但是,把它當成list來使用還是不行,比如,取第4個元素:

1 Fib(100)[4] 2 TypeError: 'Fib' object does not support indexing

要表現得像list那樣按照下標取出元素,需要實現__getitem__()方法

1 def __getitem__(self, i): 2 a, b = 0, 1 3 for x in range(i): 4 a, b = b, a + b 5 if a <= self.maximum: 6 return a 7 else: 8 raise ValueError("Out of range")

現在,就可以按下標訪問數列的任意一項了:?print("Fib(100)[4]:", Fib(100)[4])?,輸出是:?Fib(100)[4]: 3?

list還有個神奇的切片方法,Fib該如何實現呢?__getitem__()傳入的參數可能是一個int,也可能是一個切片對象slice,所以要做判斷:

1 def __getitem__(self, i): 2 if isinstance(i, int): 3 a, b = 0, 1 4 for x in range(i): 5 a, b = b, a + b 6 if a <= self.maximum: 7 return a 8 else: 9 raise ValueError("Out of range") 10 elif isinstance(i, slice): 11 if isinstance(i, slice): # i是切片 12 start = i.start 13 stop = i.stop 14 if start is None: 15 start = 0 16 a, b = 1, 1 17 L = [] 18 for x in range(stop): 19 if x >= start: 20 L.append(a) 21 a, b = b, a + b 22 return L

但是沒有對step參數作處理,也沒有對負數作處理,所以,要正確實現一個__getitem__()還是有很多工作要做的。

此外,如果把對象看成dict,__getitem__()的參數也可能是一個可以作key的object,例如str。

與之對應的是__setitem__()方法,把對象視作list或dict來對集合賦值。最后,還有一個__delitem__()方法,用于刪除某個元素:

1 def __getitem__(self, i): 2 if isinstance(i, int): # 對應于list, tuple的索引 3 a, b = 0, 1 4 for x in range(i): 5 a, b = b, a + b 6 if a <= self.maximum: 7 return a 8 else: 9 raise ValueError("Out of range") 10 elif isinstance(i, slice): # 對應于list,tuple的切片 11 if isinstance(i, slice): # i是切片 12 start = i.start 13 stop = i.stop 14 if start is None: 15 start = 0 16 a, b = 1, 1 17 L = [] 18 for x in range(stop): 19 if x >= start: 20 L.append(a) 21 a, b = b, a + b 22 return L 23 elif isinstance(i, str): # 對應于字典的dic[key]或dic.get[key] 24 print(type(i)) 25 else: 26 print("wrong type") 27 28 def __setitem__(self, key, value): # 對應于字典的dic[key] = value 29 print("key:value", key, value) 30 31 def __delitem__(self, key): # 對應于del dic[key] 32 print("del", key)

?

轉載于:https://www.cnblogs.com/z-joshua/p/6398231.html

總結

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

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