Python 中的特殊方法(定制类):__str__、__cmp__、__len__、数学运算、类型转换、@property运用、__slots__和__call__函数
Python中的特殊方法
Python的特殊方法定義在 class中,不需要直接進行顯示調用,Python的某些操作符或者函數會自動調用對應的特殊方法。這些方法如:__str__()、__len__()、__cmp__()等。下面這些更全面:
正確實現特殊方法:首先只需要編寫用到的特殊方法;其次有關聯性的特殊方法必須都實現,如編寫了特殊方法 __getattr__(),那么特殊方法 __setattr__() 和 __delattr__()也必須實現。
__str__ 和 __repr__方法:
先來看代碼示例:
class Person(object):def __init__(self, name, gender):self.name = nameself.gender = genderclass Student(Person):def __init__(self, name, gender, score):super(Student, self).__init__(name, gender)self.score = scoredef __str__(self):return '(Student: %s, %s, %s)' % (self.name, self.gender, self.score)__repr__ = __str__s = Student('Bob', 'male', 88) print s # 輸出結果為:(Student: Bob, male, 88)__str__()方法用來把一個類變成一個字符串輸出,在 class中定義該方法,可以使類按照我們想要的格式進行輸出。__str__()用于顯示給用戶,而__repr__()用于顯示給開發人員。
__cmp__()方法:
還是先看示例:
class Student(object):def __init__(self, name, score):self.name = nameself.score = scoredef __str__(self):return '(%s: %s)' % (self.name, self.score)__repr__ = __str__def __cmp__(self, s): # 定義__cmp__()方法if self.name < s.name: # 比較規則(和默認比較規則相同)return -1elif self.name > s.name:return 1else:return 0上述 Student 類實現了__cmp__()方法,__cmp__用實例自身 self和傳入的實例 s 進行比較,如果 self 應該排在前面,就返回 -1,如果 s 應該排在前面,就返回1,如果兩者相當,返回 0。
比較結果:
升級版本:先判斷類型,然后按照分數排序,分數相同按照姓名排序。如下:
class Student(object):def __init__(self, name, score):self.name = nameself.score = scoredef __str__(self):return '(%s: %s)' % (self.name, self.score)__repr__ = __str__def __cmp__(self, s):if not isinstance(s, Student):return -1else:return -cmp(self.score, s.score) or cmp(self.name, s.name)L = [Student('Tim', 99), Student('Bob', 88), Student('Alice', 99)] print sorted(L) # 結果為:[(Alice: 99), (Tim: 99), (Bob: 88)]注意:在 Python3.4.3版本之后,已經沒有cmp() 函數了。被 operator模塊中的一系列函數取代,并且使用時需要導入,如下:
import operatora, b = 'Hello', 'name' operator.lt(a, b) # 小于比較 operator.le(a, b) # 小于等于比較 operator.eq(a, b) # 等于比較 operator.ne(a, b) # 不等于比較 operator.gt(a, b) # 大于比較 operator.ge(a, b) # 大于等于比較# 可在類中編寫的內置函數如下: operator.__lt__(a, b) # 小于比較 operator.__le__(a, b) # 小于等于比較 operator.__eq__(a, b) # 等于比較 operator.__ne__(a, b) # 不等于比較 operator.__gt__(a, b) # 大于比較 operator.__ge__(a, b) # 大于等于比較__len__()函數:
如果一個類表現得像一個list,要獲取有多少個元素,就得用 len() 函數。要讓 len() 函數工作正常,類必須提供一個特殊方法__len__(),它返回元素的個數。代碼示例如下:
class Fib(object):def __init__(self, num):a, b, l= 0, 1, []for item in range(int(num)):l.append(a)a, b = b, a+bself.nums = ldef __len__(self):return len(self.nums)def __str__(self):return str(self.nums)f = Fib(10) print f # 輸出結果為:[0, 1, 1, 2, 3, 5, 8, 13, 21, 34] print len(f) # 輸出結果為:10Python 中的數學運算
Python 提供的基本數據類型 int、float 可以做整數和浮點的四則運算以及乘方等運算。但是,四則運算不局限于int和float,還可以是有理數、矩陣等。
通過定制類,計算有理數(分數形式)的加減乘除四則運算。分別編寫__add__()、__sub__()、__mul__()、__div__()函數。代碼示例如下:
def gcd(a, b):return gcd(b, a%b) if b!=0 else aclass Rational(object):def __init__(self, p, q):self.p = pself.q = qdef __add__(self, r):return Rational(self.p * r.q + self.q * r.p, self.q * r.q)def __sub__(self, r):return Rational(self.p * r.q - self.q * r.p, self.q * r.q)def __mul__(self, r):return Rational(self.p * r.p, self.q * r.q)def __div__(self, r):return Rational(self.p * r.q, self.q * r.p)def __str__(self):temp = gcd(self.p, self.q)return '%s/%s' % (self.p/temp, self.q/temp)__repr__ = __str__r1 = Rational(1, 2) r2 = Rational(1, 4) print r1 + r2 # 3/4 print r1 - r2 # 1/4 print r1 * r2 # 1/8 print r1 / r2 # 2/1Python中的類型轉換
Rational類實現了有理數運算,還可以實現int()和float()類型轉換,示例如下:
class Rational(object):def __init__(self, p, q):self.p = pself.q = qdef __int__(self):return self.p // self.qdef __float__(self):return self.p*1.0 / self.qprint float(Rational(7, 2)) # 3.5 print int(Rational(1, 3)) # 0Python中@property運用:
Python支持高階函數,在函數式編程中我們介紹了裝飾器函數,可以用裝飾器函數把設置和獲取屬性的 get/set 方法“裝飾”成屬性調用:
class Student(object):def __init__(self, name, score):self.name = nameself.__score = score@property def score(self): # 實現 get()方法return self.__score@score.setterdef score(self, score): # 實現 set()方法if score < 0 or score > 100:raise ValueError('invalid score')self.__score = score@propertydef grade(self): # 實現 grade屬性的 get()方法if self.__score < 60: return 'C'elif self.__score <80: return 'B'else: return 'A's = Student('Bob', 59) print s.grade # 輸出為:Cs.score = 99 # 輸出為:A print s.grades = Student('Bob', 59) s.score = 60 print s.score # 60 s.score = 1000 """ Traceback (most recent call last):... ValueError: invalid score """Python中限制屬性函數__slots__():
__slots__是指一個類允許的屬性列表,它的目的是限制當前類所能擁有的屬性,如果不需要添加任意動態的屬性,使用__slots__也能節省內存。
class Person(object):__slots__ = ('name', 'gender')def __init__(self, name, gender):self.name = nameself.gender = genderclass Student(Person):__slots__ = ('score') # 實際上允許的屬性還有從父類繼承來的 'name' 和 'gender'def __init__(self, name, gender, score):super(Student, self).__init__(name, gender)self.score = scores = Student('Bob', 'male', 59) s.name = 'Tim' s.score = 99 print s.score # 99Python中對類調用函數__call__():
在Python中,函數其實是一個對象,所有的函數都是可調用對象。
一個類實例也可以變成一個可調用對象,只需要實現一個特殊方法__call__()。
class Fib(object):def __call__(self, num):a, b, l= 0, 1, []for item in range(int(num)):l.append(a)a, b = b, a+breturn lf = Fib() # 獲取類對象 print f(10) # 像調用函數一樣,調用類總結
以上是生活随笔為你收集整理的Python 中的特殊方法(定制类):__str__、__cmp__、__len__、数学运算、类型转换、@property运用、__slots__和__call__函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 哔哩哔哩你懂个泡泡茶壶什么梗 意思及出处
- 下一篇: LOLS11全球总决赛LNG首发阵容 L