今天自學到類這一章節,書上讓練習自己實現類比較大小,例子是Python2版本的代碼,本人之前也沒用過Python,當初裝了python3版本,所以在實現的時候按照以前的方法一直遇到無法比較兩個類的問題,在網上也沒有找到具體説明的例子,都是零散知識點,於是去翻官網,發現一些方法,分享給像我這樣的自學者,希望能有所幫助,至於根據簡單的能想到多深就看個人了,畢竟一生二,二生三,三生萬物,如有錯誤也請前輩幫忙指正,轉載也請注明出處,謝謝:)
沒法按照Python2實現的根本原因:
python3類中找不到__cmp__()了!(dir(object)可以檢查類中屬性,你可以在交互模式下去試驗下)
1. 首先看到這你要知道的一點是(別杠哦):
在比較大小或者排序,或者求最大最小等等啥的時候系統根據什麽來判斷誰大誰小,就是默默調用了這個。
2. 好,順著問題想,那這個沒了怎麽辦,查文檔發現用這些東西替代了,不用嫌多,每個意思都很簡單(可以根據英文記哦)
__lt__ (): 小於 __gt__ :() 大於 __eq__ :() 等於 __le__ :() 小於等於 __ge__ :() 大於等於 __ne__ :() 不等於
3. 當時想的是那我要做的不就是轉變成怎麽實現這些不就能比較了嗎,然後默默找到了兩種簡單的方法,分享給大家
1)第一種方法(我覺的代碼裏面已經寫的很詳細了)
第一種方法的核心是將自己寫的函數通過轉換轉換成一開頭提到的那些__lt__那些函數
#定義一個學生類(只用於比較大小,所以能簡潔就簡潔)
class Student(object):
#如下兩個列表中的内容用來到時候生成各種各樣的學生
nameSum = ["a", "b", "c"]
ageSum = [10, 15, 20]
#學生携帶信息由姓名name,年齡age,__init__函數會在創建對象的時候自動調用,對對象初始化
def __init__(self, name = "", age = 0):
self.name = name
self.age = age
# __str__函數在此定義是因爲我們在使用print函數的時候會自動調用,輸出類中的信息
def __str__(self):
return "name:%s, age:%d"%(self.name, self.age)
#如下函數是自己定義的比較大小函數(也是前面説的樹上給的定義的例子),之前用Python2的應該就是這樣重寫這個函數的(2中名字要使用__cmp__),然後就能比較大小了,但是我們説的是Python3所以到這還不行(3中名字隨便起,反正都是自己定義的,不像2中是重寫)
def cmp(self, other):
if self.name > other.name:
return 1
if self.name < other.name:
return -1
if self.age > other.age:
return 1
if self.age < other.age:
return -1
return 0
#插入如下函數中要使用的方法對應的模塊,最好把這些寫在開頭,我放這是爲了讀的時候看的時候和思路一個順序哈哈
import random
import functools
#定義一個Students類,這個類的作用就是將之前定義的student對象類放到一個列表中方便我們使用sort()
class Students(object):
#老樣子,能簡潔就簡潔,定義一些必要的函數
#__init__函數將所有可能的名字和年齡組合生成一個個學生加入到列表中
def __init__(self):
self.studentList = []
for name in Student.nameSum:
for age in Student.ageSum:
student = Student(name, age)
self.studentList.append(student)
#待會方便我們打印排序前和排序后列表裏面的信息
def __str__(self):
res = []
for student in self.studentList:
res.append(str((student.name, student.age)))
return '\n'.join(res)
#該函數用來將列表中的學生信息排序打亂,使用random中Shuffle方法可以打亂列表中元素的順序(之前按循環生成的學生信息順序就是Ok的,所以這邊要打亂)
def shuffle(self):
random.shuffle(self.studentList)
#上面那些你衹要看懂中文注釋就行了,下面才是具體的使用方法,這邊文章想説的核心
#該函數對應了使用sort實現排序的第一種方法
#key要讓它等於你想讓他實現的方式,也就是之前定義的Student類中的cmp函數,相當於告訴系統排序的時候按照我的規則來,規則就是cmp這個函數,直接放進去是不行的,系統提供了一個轉換函數,即使用functools模塊中的cmp_to_key的方法
def sort1(self):
self.studentList.sort(key = functools.cmp_to_key(Student.cmp))
#該函數對應了使用sort實現排序的第二種方法
#這個方法調用和正常列表默認調用一樣可以看第二種方法下面一塊代碼圖的説明
def sort2(self):
self.studentList.sort()
#根據第一種方法查看結果
students = Students()
print("------------create students-------------")
print(students)
students.shuffle()
print("------------after shuffle----------------")
print(students)
students.sort1()
print("------------after sort-------------------")
print(students)
#輸出結果
------------create students-------------
('a', 10)
('a', 15)
('a', 20)
('b', 10)
('b', 15)
('b', 20)
('c', 10)
('c', 15)
('c', 20)
------------after shuffle----------------
('c', 20)
('a', 15)
('b', 15)
('b', 20)
('a', 20)
('b', 10)
('c', 15)
('c', 10)
('a', 10)
------------after sort-------------------
('a', 10)
('a', 15)
('a', 20)
('b', 10)
('b', 15)
('b', 20)
('c', 10)
('c', 15)
('c', 20)
2)第二種方法(該方法在之前的代碼上修改,請閲讀仔細,不讀下面一種也沒關係會一種也行)
第二種方法的核心就是不經過轉換函數去轉換,直接將開頭説的那些__lt__函數實現
將類中定義的這塊代碼搬家到類外面(我也不知道爲什麽在類裏面定義不能直接在類裏面的另一個函數直接調用,有大神也可以幫忙解答下)
這邊給函數改了個名字,其實你改不改都可以,如下幾步對應好操作就可以
在代碼中將__lt__等等這些函數對應實現就好(就是在類中添加上如下代碼)
#第二種定義compare的方法
def __lt__(self, other):
return cmp1(self, other) < 0
def __gt__(self, other):
return cmp1(self, other) > 0
def __eq__(self, other):
return cmp1(self, other) == 0
def __le__(self, other):
return cmp1(self, other) <= 0
def __ge__(self, other):
return cmp1(self, other) >= 0
def __ne__(self, other):
return cmp1(self, other) != 0
#根據第二種方法打印相關輸出結果(注意調用的是sort2)
students = Students()
print("------------create students-------------")
print(students)
students.shuffle()
print("------------after shuffle----------------")
print(students)
students.sort2()
print("------------after sort-------------------")
print(students)
#輸出結果
------------create students-------------
('a', 10)
('a', 15)
('a', 20)
('b', 10)
('b', 15)
('b', 20)
('c', 10)
('c', 15)
('c', 20)
------------after shuffle----------------
('a', 20)
('b', 20)
('b', 15)
('b', 10)
('c', 10)
('c', 15)
('c', 20)
('a', 10)
('a', 15)
------------after sort-------------------
('a', 10)
('a', 15)
('a', 20)
('b', 10)
('b', 15)
('b', 20)
('c', 10)
('c', 15)
('c', 20)
好了,到這就結束了,拜拜,發現寫文章比自己實驗還累。。。。