網(wǎng)站開發(fā)用啥語言廣州各區(qū)正在進一步優(yōu)化以下措施
在上一篇文章中,我們了解了函數(shù)。這一篇文章我們來了解一下Python中另外一個重要的概念:類與對象。
1、類與對象
(1)類與對象有什么關(guān)系?
你可能會奇怪,為什么要叫類與對象呢?是兩個不同的東西嗎?簡單來說,類代表一個類別,而對象則代表類的一個實例。比如我們在變量與數(shù)據(jù)類型中學習的整型變量為例。
a = 3print(type(a))
輸出結(jié)果為:
<class 'int'>
我們創(chuàng)建了一個變量 a,并賦值為 3,然后打印了它的類型??梢钥吹?#xff0c;輸出 int,代表整型變量。
細心的你也發(fā)現(xiàn)了,輸出里面有一個單詞 class,它就是類別的意思。難道說?所謂的整型,是一個類?你猜得沒錯。這里的整型:int,就是一個類。而我們創(chuàng)建的整型變量 a,就是他的一個實例。
我們再舉一些生活中的例子:
- “人”是一個類,小明則是“人”這個類的一個實例,所以小明是一個對象;
- “打車公司”是一個類,滴滴則是這個類的一個實例對象(也可以隱藏 實例 這個稱呼);
- “醬油”是一個類,海天醬油 則是一個對象;
- “車”是一個類,奔馳車則是一個對象。
細心的你不難發(fā)現(xiàn),類與對象本質(zhì)上是抽象與具象的關(guān)系,對象在類的基礎(chǔ)上進行了適當?shù)木呦?。所以在某個抽象關(guān)系中的對象也可能會成為另一個抽象關(guān)系中的類。比如上面奔馳車是車的一個對象,那同樣可能存在,奔馳車是一個類,而 S350L 是一個對象。
(2)Python 中的類
理解了類與對象,現(xiàn)在我們來看一下 Python 中的類,我們在開頭的例子中提到,類是用來把有聯(lián)系的數(shù)據(jù)和函數(shù)給組織起來的一種方式。
在類中,數(shù)據(jù)被稱為屬性,而函數(shù)則被稱為方法。每個類都可以有零個或者多個屬性,也可以有零個或者多個方法。
類的屬性和方法的概念也很適合用來描述現(xiàn)實世界,比如“人”這個類,身高、體重、年齡等就是屬性,而走路、吃飯、打球 等動作就是方法。
接下來,我們通過一個例子來演示怎么定義類,怎么使用類。
(3)定義一個“人”的類
現(xiàn)在我們嘗試定義一個人的類。需要有年齡、性別、姓名三個屬性,并提供兩個方法:introduce 方法,打印一句介紹自己的話。get_age 方法,返回當前對象的 age。
# 類的定義環(huán)節(jié)class?Person:def?__init__(self):self.name?=?""self.age?=?0self.gender?=?""def?introduce(self):print("Hello,?我是"?+?self.name)print("我今年?"?+?str(self.age)?+?"?歲")print("另外,?我是"?+?self.gender)def?get_age(self):return?self.age# 使用上面定義的類xm?=?Person()xm.name?=?"小明"xm.age?=?"25"xm.gender?=?"男生"print(xm.get_age())xm.introduce()
簡單說一下上面的代碼的主要邏輯:
- 在定義環(huán)節(jié):
- 定義了一個類:Person(類名首字母用大寫),并用 init 函數(shù)中初始化了三個屬性:name,age,gender。(init 函數(shù),前后都有兩個下劃線,代表初始化函數(shù)。簡單來說就是,當我們創(chuàng)建這個類的對象的時候,這個函數(shù)會被自動執(zhí)行,不用你再手動執(zhí)行一下)
- 定義了 introduce 方法,會把幾個屬性的值組合成一段自我介紹,這里我們通過方法參數(shù) self.屬性名 的形式來拿到類的屬性的值。這種形式叫作**點語法。**點語法的本質(zhì)就是找點前面的對象拿點后面的屬性的值。比如 A.B 代表 A對象的B屬性的值。
- 定義了 get_age 方法,把當前對象的 age 對象的值返回??梢钥吹?#xff0c;無論是 introduce 方法 還是 get_age 方法,都有一個 self 參數(shù)。這是 Python 的語法規(guī)定,類的方法的第一個參數(shù)都必須是 self。這樣方法內(nèi)部就能通過對 self 使用點語法來獲取屬性的值。
- 使用環(huán)節(jié)
- 注意從我們使用的類的代碼開始,我們這里就沒有縮進。因為有縮進就會被認為還是在類的內(nèi)部,但這里的代碼是在外部的,所以不用縮進;
- 我們創(chuàng)建了一個 Person 對象,存在變量 xm 中,之后逐一給它的屬性賦值
- 打印 xm 對象的 get_age 方法返回的值
- 調(diào)用 xm 對象的 introduce
運行后,輸出如下所示:
25Hello, 我是小明我今年 25 歲另外, 我是男生
可以看到,通過類的機制,我們成功地把數(shù)據(jù)和函數(shù)綁定在了一起。比如上面例子的數(shù)據(jù):name、age、gender 和函數(shù):get_age、introduce。并且類提供了一種機制(self 參數(shù)),能夠讓類的方法可以訪問類的屬性。
(4)給屬性賦值
回看剛剛的例子,我們創(chuàng)建了 Person 類的對象之后,逐一對他的屬性賦值,每一次屬性賦值都需要針對 xm 對象使用點語法,比較麻煩,有沒有更好的方式呢? 答案是肯定的。
我們稍微改造一下剛才的例子,改造后的代碼如下所示:
class?Person:def?__init__(self,?name,?age,?gender):self.name?=?nameself.age?=?ageself.gender?=?genderdef?introduce(self):print("Hello,?我是"?+?self.name)print("我今年?"?+?str(self.age)?+?"?歲")print("另外,?我是"?+?self.gender)def?get_age(self):return?self.agexm?=?Person("小明",?25,?"男生")print(xm.get_age())xm.introduce()
執(zhí)行之后,輸出和剛才是一致的:
25Hello, 我是小明我今年 25 歲另外, 我是男生
不同在哪兒呢?是這里。
現(xiàn)在我們不需要進行逐個屬性的賦值,而是在構(gòu)造對象的階段就完成了幾個屬性的初始化。
這其中的奧妙就在 init 方法里,我們給 init 函數(shù)加了參數(shù),然后用這些參數(shù)直接在 __init__的函數(shù)體中給我們的屬性賦值。這樣直接在創(chuàng)建對象的時候,把對應的值依次放在類名后的括號中,用逗號分隔。就能實現(xiàn)一次性地給屬性都賦值,精簡了代碼。
2、常見的系統(tǒng)類
類和函數(shù)一樣,類同樣也有 Python 的開發(fā)者們提前寫好提供給我們使用的類,一般稱為系統(tǒng)類。上面舉的例子都是我們自己實現(xiàn)的類,下面來看一下常用的系統(tǒng)類。
(1)列表(list)
列表相信大家都不陌生,在變量與數(shù)據(jù)類型文章中已經(jīng)介紹過,它是 Python 非常常用的數(shù)據(jù)類型。
這里介紹一下列表的基礎(chǔ)使用,代碼如下:
#?創(chuàng)建列表a?=?[90,1,23,?15]#?訪問某個元素(下表從?0?開始)print("Third?number?is?",a[2])#?使用?append?方法添加元素a.append(-1)print("After?append:?",?a)#?刪除某個位置的元素del?a[1]print("After?delete?second?number:?",?a)#?刪除具體某個元素a.remove(15)print("After?delete?15:",?a)#?排序,默認從小到大a.sort()print("After?sort",?a)#?逆排序,從大到小a.sort(reverse?=?True)print("After?reverse?sort",?a)#?求長度print("Length:?",?len(a))
上面主要方法都有注釋,這里不再展開,你可以結(jié)合以下輸出和代碼,加深理解。重要的是你要知道,如果之后讓你做某個事(刪除、排序等),你能直接使用 list 類對應的方法。而不需要自己寫循環(huán)完成。
Third number is 23After append: [90, 1, 23, 15, -1]After delete second number: [90, 23, 15, -1]After delete 15: [90, 23, -1]After sort [-1, 23, 90]After reverse sort [90, 23, -1]Length: 3
(2)字符串(string)
字符串我們用的也是非常多的,在之前也介紹過一些基礎(chǔ)用法,比如用 + 號來連接兩個字符串,這里我們再介紹額外的一些用法。
a?=?"Hello,this?is?my?home,welcome"#?添加字符a?=?a?+?",pp"print("\nAfter?append?pp:\n",?a)#?刪除前?x?個字符,比如?3a?=?a[3:]print("\nAfter?remove?first?3?characters:\n",?a)#?刪除固定內(nèi)容的字符a?=?a.replace("my","")print("\nAfter?remove?'my':\n",?a)#?替換固定內(nèi)容成另外一個字符串a(chǎn)?=?a.replace("home",?"company")print("\nAfter?replace?'home'?to?'company':\n",a)#?用某個字符分割字符串,返回一個數(shù)組,比如逗號str_list?=?a.split(",")print("\nList?split?from?string?by?comma:\n",?str_list)
輸出:
After append pp:Hello,this is my home,welcome,ppAfter remove first 3 characters:lo,this is my home,welcome,ppAfter remove 'my':lo,this is home,welcome,ppAfter replace 'home' to 'company':lo,this is company,welcome,ppList split from string by comma:['lo', 'this is company', 'welcome', 'pp']
3、字典(dict)
字典和列表、字符串一樣,也是 Python 中相對常用的數(shù)據(jù)類型,同樣也是系統(tǒng)類。因為復雜一些,所以在變量與數(shù)據(jù)類型文章中沒有介紹。
字典和列表類似,也是存儲多個變量的容器。但與列表不同的是,字典存儲的不僅僅只有變量,還有變量之間的映射關(guān)系。
我們舉個例子,假設(shè)我們要存儲班級里三位同學的年齡,可以用列表來完成,比如 a = [17, 18, 15], 但如果我們不僅要存儲年齡,還得存儲這三位同學的名字。那用列表就無能為力了。
簡單來說,我們希望存儲一個名字-年齡的映射關(guān)系。在這個例子上就是要存儲這種形式的數(shù)據(jù):小明:17,小紅:18,小江:15。在 Python 中,這種有對應關(guān)系的兩個變量我們稱之為鍵值對。比如小明就是 鍵(key),而 17 就是值(value),一個鍵會唯一對應到一個值。
這里我們希望存儲的就是三個鍵值對。而字典,就是專門用來存儲鍵值對的容器。
#?創(chuàng)建一個空字典,用?花括號?{}d?=?{}print("Empty?dict:",?d)#?用鍵值對創(chuàng)建字典,鍵和值中間用冒號隔開,不同的鍵值對用逗號隔開d?=?{"xiaoming"?:?3.5?,?"xiaohong":?4}print("Two?key-value?pair?dict:",?d)#?訪問字典的元素,和列表一樣用中括號,但傳入?key,查詢?value。比如查詢?xiaoming?的年齡print("Xiaoming's?company?age:",?d["xiaoming"])#?添加新的鍵值對,直接對?key?對應的?value?賦值即可d["xiaogang"]?=?5.5print("After?append?xiaogang:",?d)#?刪除鍵值對,類似列表刪除,只是中括號內(nèi)寫?key,而不是序號del?d["xiaohong"]print("After?remove?xiaohong:",?d)#?修改鍵值對,同添加一樣,直接對某個已有的?key?重新賦值即可d["xiaoming"]?=?9.3print("After?change?xiaoming's?value:",?d)
輸出:
Empty dict: {}Two key-value pair dict: {'xiaoming': 3.5, 'xiaohong': 4}Xiaoming's company age: 3.5After append xiaogang: {'xiaoming': 3.5, 'xiaohong': 4, 'xiaogang': 5.5}After remove xiaohong: {'xiaoming': 3.5, 'xiaogang': 5.5}After change xiaoming's value: {'xiaoming': 9.3, 'xiaogang': 5.5}
3、實戰(zhàn)
現(xiàn)在有個任務,記錄部門信息,每個部門都需要統(tǒng)計部門名稱,員工列表,部門主管等信息。另外,還有兩個要求:1、部門員工入職和離職都能方便的更新信息;2、可以方便查看某個部門的匯總信息。
問題分析:
- 目前我們需要記錄的信息都是圍繞部門這個實體的,所以我們可以用一個部門的類來記錄,部門名稱、員工列表和部門主管則都是這個類的屬性。
- 另外的要求是有人員變動的時候方便更新信息,那其實就是部門類需要提供增加人員和減少人員的方法。
- 最后一個要求是方便查看部門匯總,那其實就是需要一個打印方法,來把部門的屬性都打印出來。
我們接下來一步步來實現(xiàn)它。
(1)創(chuàng)建部門類
我們首先創(chuàng)建部門類和它的屬性,部門名稱和主管姓名,是字符串類型的變量,這兩個屬性我們通過初始化函數(shù)的參數(shù)來初始化。而員工列表是一個列表類型,我們先把它初始化成一個空列表。
class?Department:def?__init__(self, dep_name,?boss_name):self.dep_name?=?dep_nameself.boss_name?=?boss_nameself.stuff_list?=?[]
(2)實現(xiàn)員工的新增方法
目前員工列表,也就是 stuff_list 屬性還是空列表,為了實現(xiàn)往這個列表增加員工的名字,我們需要在部門類增加一個添加員工的方法,我們就命名為 add_stuff。這個方法除了類方法必須帶的 self 參數(shù)之外,只有一個參數(shù):要添加的員工的姓名。
然后方法里面只需要把這個姓名添加到 stuff_list 即可,添加數(shù)據(jù)到列表,只需要調(diào)用列表對象的 append 方法即可。
class?Department:def?__init__(self,dep_name,?boss_name):self.dep_name?=?dep_nameself.boss_name?=?boss_nameself.stuff_list?=?[]#?新增代碼def?add_stuff(self,?name):self.stuff_list.append(name)
(3)實現(xiàn)刪除員工的方法
部門會新增員工,比如員工入職,或者調(diào)入。也可能會減少員工,比如員工離職,比如轉(zhuǎn)崗去其他部門,所以我們同樣需要一個刪除員工的方法。
類似添加員工的設(shè)計,刪除員工的方法同樣需要員工姓名的參數(shù),在方法內(nèi)部調(diào)用 stuff_list 對象的 remove 方法來將員工從列表中移除。
class?Department:def?__init__(self,dep_name,?boss_name):self.dep_name?=?dep_nameself.boss_name?=?boss_nameself.stuff_list?=?[]def?add_stuff(self,?name):self.stuff_list.append(name)#?新增代碼def?remove_stuff(self,?name):self.stuff_list.remove(name)
(4)添加打印部門信息的方法
打印部門信息,就是將部門的三個屬性直接打印出來,比較簡單,這里我們直接實現(xiàn):
class?Department:def?__init__(self,dep_name,?boss_name):self.dep_name?=?dep_nameself.boss_name?=?boss_nameself.stuff_list?=?[]def?add_stuff(self,?name):self.stuff_list.append(name)def?remove_stuff(self,?name):self.stuff_list.remove(name)# 打印部門信息def print_dep_info(self):print("部門名稱:",self.dep_name);print("主管名稱:",self.boss_name);#這里使用上一篇文章中說到的len()函數(shù)來計算部門人數(shù)print("員工共個:",len(self.stuff_list));print("分別是:",self.stuff_list);
(5)使用部門類
現(xiàn)在,我們的部門類已經(jīng)開發(fā)完畢了,現(xiàn)在讓我們來用一用它,看看它是不是好使。
首先是記錄部門信息,假設(shè)現(xiàn)在先記錄2個部門:技術(shù)部和財務部。首先要分別創(chuàng)建兩個部門的對象:
#創(chuàng)建技術(shù)部和財務部
it_dep = Department("技術(shù)部","小江");
finance_dep = Department("財務部","小紅");#給技術(shù)部添加兩個員工
it_dep.add_stuff("小江1");
it_dep.add_stuff("小江2");#給財務添加兩個員工
finance_dep.add_stuff("小紅1");
finance_dep.add_stuff("小紅2");
#打印技術(shù)部和財務部信息
it_dep.print_dep_info();
finance_dep.print_dep_info();
執(zhí)行后輸出:
部門名稱: 技術(shù)部
主管名稱: 小江
員工共個: 2
分別是: ['小江1', '小江2']
部門名稱: 財務部
主管名稱: 小紅
員工共個: 2
分別是: ['小紅1', '小紅2']
最后,當有人需要離職時,只需要調(diào)用 remove_stuff 方法即可,假設(shè) 技術(shù)部的小江2決定去創(chuàng)業(yè),要離職,我們需要將他從部門列表中移除。
it_dep.remove_stuff("小江2")it_dep.print_dep_info()
輸出
部門: 技術(shù)部主管: 小江員工共個:1員工: ['小江1']
可以看到,小江2已經(jīng)不在員工列表中了。
至此,我們通過類與對象的方法,完成了部門信息統(tǒng)計的任務,并且可以非常方便地處理員工增加和減少的場景。