1. 程式人生 > >Python面向物件程式設計總結(上)

Python面向物件程式設計總結(上)

在我學習python之前一直認為python是指令碼型語言,不能用面相物件的方法進行程式設計,當我學習了python之後我發現我錯了,python不但支援面相物件而且使用的人還挺多的。我從接觸程式設計開始就是學習的Java語言,所以面相物件程式設計的思想在我的腦海裡根深蒂固,讓我一下從面向物件程式設計轉換到面向過程程式設計還有一些不適應呢,所以我就來總結一下python面向物件程式設計的方法和過程。我將按照面向物件的構成要素來分析,依次為類和例項、屬性、方法、封裝、繼承、多型,如果有什麼問題還請大家積極指出,我所用的版本為python2.7!

一、類和例項

面向物件是一種程式設計思想,它將現實生活中的事物對映到程式世界中,所以我們可以使用現實生活中的思想來考慮程式設計問題,這使我們程式設計變得更加容易,畢竟我們都已經在現實生活中生活了幾十年了嘛。

我們來看一下python中類的基本形式。

class Movie(object):

    def __init__(self,name,length):
        self.name = name
        self.length = length

    def print_name(self):
        print '電影的名稱是:%s' % (self.name,)

class Movie(object): 是固定寫法,class表明正在宣告的是一個類,Movie是類名,(object)表示繼承自那些父類,就行java一樣,所有的類都是繼承自object類的,所以如果你寫的不繼承自其他的類就將其寫成繼承自object,當繼承自object,括號連同括號裡的object都可以省略寫成:class Movie:

第一個方法__init__是構造方法,構造方法的第一個引數永遠是self,表示這個類的物件本身,真正構造物件時,self這個引數不用寫,python編譯器會自己加上去,構造方法的作用就是對self物件進行賦值,如上面的將電影的名字和長度賦給self。

對於上面的Movie類我們可以用下面的程式碼來呼叫它:

import OOP

movie = OOP.Movie('大聖歸來',90)
movie.print_name()

輸出的結果是:電影的名稱是:大聖歸來

如果不需要給物件傳遞什麼引數,那麼構造方法也是可以省略的,例如:

class Movie(object):

    def
print_info(self):
print '這是一個電影的類'

這樣在構造物件時就不用傳遞任何的引數例如:

import OOP

movie = OOP.Movie()
movie.print_info()

輸出的結果為:這是一個電影的類

二、屬性

1、例項屬性

例項屬性是歸物件所有,每個物件都有自己的一套屬性,不同物件之間的例項屬性不會相互干擾。在python中,在__init__方法中宣告的屬性就是例項屬性。當然,你也可以在類中的任何一個方法中,使用self.var=something 的方式宣告例項屬性,但是我個人覺得這樣會使程式非常混亂,容易出錯,下面用這個例子來看一下:

OPP

# -*- coding: utf-8 -*-

class Movie(object):

    def __init__(self,name,length):
        self.name = name
        self.length = length

    def print_name(self):
        self.aaa = '123'
        print '電影的名稱是:%s' % (self.name,)

OOPTest

# -*- coding: utf-8 -*-

import OOP

movie1 = OOP.Movie('大聖歸來',90)
movie2 = OOP.Movie('美人魚',120)

print movie1.name
print movie2.name

movie1.print_name()
print movie1.aaa #只有在呼叫了print_name方法之後,aa才會被定義

movie1.name='風聲'
print movie1.name
print movie2.name #movie1的改變並未影響到movie2

輸出結果:
大聖歸來
美人魚
電影的名稱是:大聖歸來
123
風聲
美人魚

2、類屬性

類屬性是歸這個類所有的,所有的例項都共享著一個變數,如果一個例項改變了類屬性的值,那麼所有的例項都會受到影響。類屬性的宣告獨立於所有方法,宣告方法如下:

OOP

# -*- coding: utf-8 -*-

class Movie(object):

    count = 1 #類屬性

    def __init__(self,name,length):
        self.name = name
        self.length = length

    def print_name(self):
        self.aaa = '123'
        print '電影的名稱是:%s' % (self.name,)

上面的count就是一個類屬性,類屬性就類似於java中static變數,可以使用類名.count的方式進行呼叫,當然也可以通過例項.count的方式進行呼叫,類屬性一般用於計數物件,或者不同例項之間共享變數,看下面的例子來理解一下類變數。

# -*- coding: utf-8 -*-

import OOP

movie1 = OOP.Movie('大聖歸來',90)
movie2 = OOP.Movie('美人魚',120)

print OOP.Movie.count #1 通過類名.count的方式進行呼叫
print movie2.count #1 通過例項.count的方式進行呼叫

movie1.count = 3
print OOP.Movie.count #1
print movie1.count #3
print movie2.count #1

OOP.Movie.count=3
print OOP.Movie.count #3
print movie1.count #3
print movie2.count #3

註釋中是輸出的結果,我們可以看到如果使用類名.count的方式進行呼叫,那麼所有的例項中的值都將改變,但是如果通過例項.count的方式進行呼叫,那麼只有相應的例項的值發生了改變。

三、方法

Python的方法並不像C#,Java這些編譯性語言那樣嚴格的區分靜態方法和例項方法。也就是說Python的靜態方法,類方法和例項方法只是在呼叫上有區別,型別和例項都可以呼叫。

1、例項方法

例項方法可以被類例項呼叫,通過例項.方法的形式進行呼叫,這個我們都不陌生了,上面例子中的print_name方法就是例項方法,使用例項方法是傳入的引數方法宣告時的引數少一個,因為第一個引數self是不用提供的。除此之外例項方法還可以被類呼叫,形式是類名.方法名(self),必須手動新增self變數,也就是類的例項。

2、類方法

類方法可以被類和類例項呼叫,但是類方法無法訪問例項變數,只能方法訪問類變數,宣告時在方法前面加上@classmethod,並且方法中的第一個引數是cls而不是self,和例項方法一樣,使用時第一個引數不用傳遞,python的編譯器會自動的加上。類方法更像java中的static方法。

3、靜態方法

靜態方法可以被類和類例項呼叫,無法訪問例項變數和類變數,只能方法傳入進來的引數,宣告時在方法前面加上@staticmethod,靜態方法沒有預設的引數,靜態方法有點像函式工具庫的作用。

OOP

# -*- coding: utf-8 -*-

class Movie(object):

    count = 1

    def __init__(self,name,length):
        self.name = name
        self.length = length

    #例項方法
    def print_name(self):
        self.aaa = '123'
        print '電影的名稱是:%s' % (self.name,)

    #類方法
    @classmethod
    def print_len(cls):
        print '電影的長度是:%d' % (cls.count,)

    #靜態方法
    @staticmethod
    def print_info(str):
        print '傳入的資訊是:%s' % (str,)

OOPTest

# -*- coding: utf-8 -*-

import OOP

movie1 = OOP.Movie('大聖歸來',90)

movie1.print_name() #通過例項呼叫例項方法
OOP.Movie.print_name(movie1) #如果通過類呼叫例項方法,必須手動傳入例項

OOP.Movie.print_len() #通過類呼叫類方法
movie1.print_len() #通過例項呼叫類方法

OOP.Movie.print_info('哈哈') #通過類呼叫靜態方法
movie1.print_info('哈哈') #通過例項呼叫靜態方法

剩下的還有很多,一次寫不完,下一篇在討論封裝、繼承和多型,謝謝大家的支援!