Python面向對象編程基礎
類:
我們最先想到的就是分類:人,動物,植物...這些都是自然界的大類;
每個類別都有自己的特征與行為,而類就是描述這些具有相同屬性與方法的對象的集合。
通過一個圖來全面了解面向對象基本概念:
屬性:
類具有的特征,對於人類來說,身高、體重、性別等是基本屬性;
方法:
類具有的功能,對於人來來說:吃飯、睡覺、工作等是通用方法;
實例:
類對應的一個具體對象,比如梅西,詹姆斯都是實際存在的人;
方法:
對象行為的描述,對於人類來說,吃飯,睡覺,工作都是方法;
還有一些其他基本概念,我們通過Python來實際講解。
1:類基本語法
1.1:定義類
先來看基本語法:
class 類名:
pass
#例如:
class Person:
pass
1>class 為關鍵字;
2>Person為類名稱;
人類有一些共同特征與方法,我們如何在類中添加?
1.2:添類屬性
人類中有公共屬性,例如:居住在地球,氧氣和水是必需品;我們可以將其添加到類中:
class Person: #居住星球 start = ‘Earth‘ #必須品:水,實物,氧氣 needlist = [‘water‘, ‘food‘,‘oxygen‘]
我們可以直接訪問這些屬性:
print(Person.star)
print(Person.needlist)
輸出結果:
print(Person.star)
print(Person.needlist)
人類有一些共同方法,例如:吃飯,睡覺,工作等,如何添加到類中?
添加方法:
python中類方法分為實例方法,類方法,靜態方法,其他語言中也有這些概念,可能語法不同,但是基本概念類似,我們先來看實例方法,基本語法如下:
class 類名:
def func_name(self, *args, **kwargs):
pass
1>類中添加實例方法,與定義函數類似,def關鍵字+方法名+參數;
2>實例方法的第一個參數必須是self,這是基本語法;
3>實例方法不能直接調用,只有具體對象才能調用;
添加人類方法:sleep,eat,work,say;代碼實現如下:
class Person:
#居住星球
star = ‘Earth‘
#必須品:水,實物,氧氣
needlist = [‘water‘, ‘food‘,‘oxygen‘]
#第一個參數:self
def eat(self, foodlist):
pass
def sleep(self):
pass
def work(self, tasklist):
pass
def say(self, what):
pass
後面實際工作與學習中,如果我們對類掌握十分熟悉,可以先把屬性與接口定義出來,然後逐步完善每一個方法就可以,為了方便後面觀察調用過程,我們給每個方法加上輸出信息:
class Person:
#居住星球
star = ‘Earth‘
#必須品:水,實物,氧氣
needlist = [‘water‘, ‘food‘,‘oxygen‘]
#第一個參數:self
def eat(self, foodlist):
print(‘I eat:‘,foodlist)
def sleep(self):
print(‘I am sleep now‘)
def work(self, tasklist):
print(‘my work is:‘, tasklist)
def say(self, what):
print(‘I say:‘, what)
類定義好了,我們如何來使用呢,來創建具體人的對象,實例化:
實例化
創建一個對象,對於剛才例子我們可以使用下面方式:
p1 = Person()
p2 = Person()
p2與p2就是Person類對應的兩個對象,也成為實例,如何調用eat, sleep等方法?
使用實例p1,p2還是Person?當有疑問時,我們可以通過實際操作驗證:
p1.sleep()
Person.sleep()
輸出結果:
I am sleep now
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-6-3a15402f300a> in <module>()
1 p1.sleep()
----> 2 Person.sleep()
TypeError: sleep() missing 1 required positional argument: ‘self‘
第一條語句正常輸出,第二條是錯誤的,因為需要參數self;
這裏我們有必要把這個搞清楚:
1>Person類中的方法都是實例方法,他的第一個參數必須是self,那麽self究竟是誰?
2>如果是實例直接調用,那麽self,就是實例自己,比如,p1,p2;
3>類不能直接調用實例方法,因為沒有與實例進行綁定,但是可以換一種方式調用;
下面我們來驗證self究竟是誰,對代碼進行修改:
#定義最簡Person類
class Person:
def whoami(self):
print(‘I am 0x%x‘%id(self))
#創建對象
p = Person()
#id函數:顯示對象內存地址
print(‘p id:0x%x‘%id(p))
#對象調用實例方法
p.whoami()
#不推薦使用,只是用來理解實例方法,
#實例方法第一參數必須是類的一個實例
Person.whoami(p)
輸出結果( 輸出地址可能不同):
p id:0x7f99c06d4fd0
I am 0x7f99c06d4fd0
I am 0x7f99c06d4fd0
通過這裏例子,希望對大家理解實例方法有幫助。
重要的__init__方法
定義人類了,但人有名稱,年齡等自己特征,如何在實例化時候指定這些屬性,這裏我們需要使用__init__方法,我們先來添加一個__init__方法,看一下調用過程。
#添加__init__方法
class Person:
def __init__(self, name):
print(‘call init name:‘, name)
#實例化時,添加名稱
p1 = Person(‘sun‘)
p2 = Person(‘li‘)
輸出結果為:
call init name: sun
call init name: li
我們並沒有顯示調用__init__方法,這是怎麽回事?
實例化過程會默認調用__init__方法,調用__init__時,實例已經創建出來,這個方法的參數對應實例化時傳遞參數,目的:初始化對象的屬性。比如名稱,如何添加實例屬性?
類屬性與實例屬性
首先來看類屬性,我們人類都屬於地球,所以我們添加一個屬性:
class Person:
#居住星球
star = ‘Earth‘
name = ‘unknow‘
p1 = Person()
#訪問star與name
print(p1.star, p1.name)
輸出結果:
Earth unknow
這裏我們訪問p1的star與name其實訪問的是類屬性。
添加實例屬性:
#既簡單又粗暴
p1.name = ‘sun‘
print(p1.star, p1.name)
輸出結果:
Earth sun
思考問題:這時候Person類中的name是什麽?做實驗驗證:
print(‘p1.name:‘,p1.name)
print(‘Person.name:‘,Person.name)
輸出結果:
p1.name: sun
Person.name: unknow
分析下上面步驟:
1>p1.name=sun,修改了什麽?它只是對p1增加name屬性,值為sun,對其他對象與Person類沒有任何影響;
2>p1與Person中有了name屬性,p1訪問時,選擇哪個?如果實例中有name屬性,使用實例中屬性,如果沒有,去類中查找,若類中不存在報異常。
下面我們在__init__方法中直接添加實力屬性,實例化時直接添加名稱與年齡:
class Person:
name = ‘unknow‘
def __init__(self, name, age):
self.name = name
self.age = age
def selfintroduction(self):
print(‘my name is %s, I am %d years old.‘%(self.name, self.age))
p1 = Person(‘sun‘, 10)
p1.selfintroduction()
輸出結果:
my name is sun, I am 10 years old.
我們有個問題,實例中的name與age被放到哪裏,通過__dict__看下:
print(‘Person:‘,Person.__dict__)
print(‘p1:‘,p1.__dict__)
輸出結果:
Person: {‘__module__‘: ‘__main__‘, ‘name‘: ‘unknow‘, ‘__init__‘: <function Person.__init__ at 0x7f99c0748d90>, ‘selfintroduction‘: <function Person.selfintroduction at 0x7f99c0748bf8>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘Person‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘Person‘ objects>, ‘__doc__‘: None}
p1: {‘name‘: ‘sun‘, ‘age‘: 10}
通過輸出信息,我們可以看到這些值存放方式,可以通過這種方式直接賦予實例新的屬性,但是我們不推薦這種方式。
總結
這節我們主要內容:
1>面向對象基本概念:類,對象,屬性,方法;
2>Python中類定義及實例化過程;
3>__init__方法及屬性查找過程;
到這裏我們對類有了基本了解,後面內容中我來介紹類的具體使用及高級使用方式。
Python面向對象編程基礎