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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

定制类

發布時間:2025/3/20 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 定制类 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

形如__xxx__的變量或者函數名就要注意,這些在Python中是有特殊用途的。如__len__()方法是為了能讓class作用于len()函數。

除此之外,Python的class中還有許多這樣有特殊用途的函數,可以幫助我們定制類。

1、字符串定制__str__

首先頂一個一個Person 類,通過輸出一個實例引入定制類的問題

#Coding = utf- 8class Person(object):def __init__(self,name):self.name = nameprint Person("rhx") 輸出結果:<__main__.RoundFloatManual object at 0x00000000056A24E0>

其實本來是想輸出實例化對象的,但是輸出的確實地址信息,如何才能按照想要輸出的形式顯示呢?

此時就需要使用 __str__方法,返回一個字符串

#Coding = utf- 8class Person(object):def __init__(self,name):self.name = name def __str__(self):return "Person object (name: %s)" %self.nameprint Person("rhx") 輸出結果:Person object (name: rhx)

但是知道,實例化對象時如果沒有把這個實例對象保存到一個變量中,它很快就沒有了,會被自動垃圾收集器回收,因為沒有任何引用指向這個實例,所以對于Person('rhx')實例化對象,如果沒有賦值給一個變量,實例創建時會給其分配一塊內存,隨即會釋放掉它。在python命令行中如果直接調用實例化對象的變量,卻也得不到想要的輸出結果

>>> class Person(object): ... def __init__(self,name): ... self.name = name ... def __str__(self): ... return "Person object (name: %s)" %self.name ... >>> p = Person("rhx") >>> p <__main__.Person object at 0x0000000004A829E8>

注意這里是在Python(command line),而第一個部分的IDE是pycharm.輸出結果也是一個地址值,那如何得到期望的結果呢?

這是因為直接顯示變量調用的不是 __str__() 而是 __repr__(),兩者的區別是 __str__ 返回的是用戶可見的字符串,而 __repr__ 返回的是開發者看到的字符串,也就是說 __repr__ 是為提調試服務的,即是在解釋器中轉儲對象時,顯示的是默認對象符號,因此如果要想修復它,只需要覆蓋__repr__(),一個簡單的辦法是把__str__()的實現代碼復制給__repr__(),但是要是__str_的實現方法存在問題,那么同樣會把該bug帶給__repr__,由于python中一切皆對象,因此可以將__str__()這個對象的引用賦值給__repr__,因此有:

>>> class Person(object): ... def __init__(self,name): ... self.name = name ... def __str__(self): ... return "Person object (name: %s)" %self.name ... __repr__= __str__ ... >>> p = Person("rhx") >>> p Person object (name: rhx)

2、數值定制__add__

在字符串定制中,可以通過__str__進行有意義的輸出顯示,那對于類中的對象如何實現加法呢

class Time(object):def __init__(self,hr,min):self.hour = hrself.minute = mindef __str__(self):return '%d:%d' % (self.hour,self.minute)__repr__ = __str__mon = Time(10,20) tue = Time(9,35) print mon print tueprint mon + tue 輸出結果: 10:20 Traceback (most recent call last): 9:35File "F:/py_test/Python Advanced/RoundFloat2.py", line 25, in <module>print mon + tue TypeError: unsupported operand type(s) for +: 'Time' and 'Time'

對象實例化的時候可以正常顯示,但是無法運行加法運算。因此需要對其進行重載,重載較為簡單,如+,只需要重載__add__()方法,那如何處理這個總數,因為相加之后是一個新的Time對象,并沒有對mon和tue對象進行修改,因此需要創建一個新的對象并填入計算出來的總數

def __add__(self, other):return self.__class__(self.hour+other.hour,self.minute+other.minute)

和普通情況一下,新的對象是通過調用類來實現的,不過這里不是使用的Time類,而是使用__class__,在類中,一般不直接使用類名,而是使用self的__class__屬性,實例化self的那個類,并調用它。

此外還希望實現“原位”操作,如 += 的形式,在原來變量的基礎上增加一個量,即是原位加法, __iadd__(),用來支持想 mon += tue的加法形式,重載一個 __i*__()方法額唯一秘密在它必須返回self,這樣不難理解,在原來對象的基礎上進行增量加法

def __iadd__(self, other):self.hour += self.hour + other.hourself.minute += self.minute + other.minute

3、__iter__

? ? ? ? 迭代器就是有一個next()方法的對象,而不是通過索引來計數,當一個循環機制(例如for...)需要下一項時,調用迭代器的next()方法就可以獲得它,條目全部獲取完之后,引發一個StopIteration異常,告訴外部調用者,迭代完成,對于如何創建一個迭代器呢,對于一個對象調用iter()就可以得到它的迭代器。如何在類中實現

class Fib(object):def __init__(self):self.a,self.b = 0,1 #菲波那切數列的前兩項def __iter__(self):return selfdef next(self):self.a ,self.b = self.b,self.a + self.b #數列迭代if self.b >= 5000:raise StopIterationreturn self.a for n in Fib():print n

4、元素獲取__getitem__

雖然在上面實現了Fib類的迭代,使其用起來想list,但是要像list一樣獲取一個元素的時候,是否可以呢?

print "The second number of Fib: %d" %Fib()[7] 輸出結果:print "The second number of Fib: %d" %Fib()[7] TypeError: 'Fib' object does not support indexing

因此如果想要像list那樣按照下表進行訪問的話,需要實現 __item__()方法

def __getitem__(self, item):a,b = 1,1for i in range(item):a,b = b,a + breturn a這樣就可以進行切片操作了




總結

以上是生活随笔為你收集整理的定制类的全部內容,希望文章能夠幫你解決所遇到的問題。

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