面向對象編程是Python中的核心之一,面向對象的核心並非概念,語法,使用有多麼複雜,而是一種編程思想,並非掌握了類建立與使用就真正掌握了面向對象編程,這須要在不斷工做與練習中逐步提高;拋去代碼,咱們先來看現實世界的基本概念:python
咱們最早想到的就是分類:人,動物,植物...這些都是天然界的大類;
每一個類別都有本身的特徵與行爲,而類就是描述這些具備相同屬性與方法的對象的集合。
經過一個圖來全面瞭解面向對象基本概念:編程
類具備的特徵,對於人類來講,身高、體重、性別等是基本屬性;ide
類具備的功能,對於人來來講:吃飯、睡覺、工做等是通用方法;函數
類對應的一個具體對象,好比梅西,詹姆斯都是實際存在的人;
每一個實例都有本身實際屬性與方法,好比詹姆斯的姓名,體重等;學習
對象行爲的描述,對於人類來講,吃飯,睡覺,工做都是方法;ui
還有一些其餘基本概念,咱們經過Python來實際講解。code
先來看基本語法:對象
class 類名: pass #例如: class Person: pass
1>class 爲關鍵字;
2>Person爲類名稱;接口
人類有一些共同特徵與方法,咱們如何在類中添加?ip
人類中有公共屬性,例如:居住在地球,氧氣和水是必需品;咱們能夠將其添加到類中:
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__方法 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__方法及屬性查找過程;
到這裏咱們對類有了基本瞭解,後面內容中我來介紹類的具體使用及高級使用方式。