1. 程式人生 > >Python面向對象編程基礎

Python面向對象編程基礎

say cts 編程 posit UNC 通用 函數類 面向對象 ipy

面向對象編程是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面向對象編程基礎