天天看點

Python回顧與整理2:Python對象

     說對象是面向對象程式設計語言最重要的一部分一點也不為過,沒有了“對象”,面向對象将無從談起。Python也是如此,如果無法掌握對象,你很難有大的進步與提升。

1.Python對象

(1)對象特性

        Python使用對象模型來存儲資料,構造任何類型的值都是一個對象,所有的Python對象都擁有下面的三個特性:

身份:每個對象一唯一身份辨別,可使用内建函數id()檢視該值(可以認為這個值是該對象的内在位址)

類型:對象的類型決定了對象(可以儲存什麼類型的值,進行什麼樣的操作,遵循什麼樣的規則),可以使用内建函數type()檢視(對象的類型也是一個對象,是以type()傳回的是一個對象,而不是字元串)

值:對象表示的資料項

        對于身份特性,它是可讀的;對于類型特性,新式類型和類可以修改,但不建議初學者這樣做,另外Python有一系列的基本(内建)資料類型,可以自己定義(一般推薦通過建立和執行個體化類來對特定的資料進行存儲);對于值,取決于該對象是否支援更新操作。

(2)對象屬性

        Python使用句點标記法來通路屬性,最常用的屬性是函數和方法,當然一些Python對象也有資料屬性。

2.标準類型

數字(分為幾個子類型,有三個是整型)

Integer    整型

Boolean    布爾型

Long integer    長整型

Floating point real number    浮點型

Complex number    複數型

String    字元串

List            清單

Tuple         元組

Dictionary  字典

        需要注意的是,使用上面這些基本類型所構造的值都為該類型對應的對象。

3.其他内建類型

類型

Null對象(None)

檔案

集合/固定集合

函數/方法

子產品

下面主要說明Type和None類型,其它的後面會讨論。

(1)類型對象和type類型對象

        前面提到,對象有一系列行為和特性,而這些資訊就是儲存在對象的類型當中:

        type()傳回的是一個類型對象,表明42是一個數字類型對象,而<type 'int'>本身也有所屬于的類型,可以繼續使用type()來檢視:

        <type 'type'>表示<type 'int'>是一個type類型對象,嘗試繼續使用内建函數type()來作進一步操作:

        得到的還是type類型對象,于是可以有下面的結論:

所有類型對象的類型都是type,它也是所有Python類型的根和所有Python标準類的預設元類(metaclass)

在Python中,類就是類型,執行個體是對應類型的對象(類比42的例子,42屬于數字類型,它是數字類型構造值後的一個數字對象,或者說42是類int的一個執行個體對象,因為現在類型就是類)

(2)None:Python的Null對象

        Python有一個特殊的類型,被稱為Null對象或者NoneType,它隻有一個值,那就是None

        None沒有什麼有用的屬性,它的布爾值總是False。

(3)布爾值

        前面提及布爾值,有以下幾點注意:

每個對象天生具有布爾True或False值

空對象 值為零的任何數字或者Null對象的布爾值都是False

使用者建立的類執行個體如果定義了nonzero(__nonzero__())或length(__len__())且值為0,那麼它們的布爾值就是False

4.内部類型

代碼

跟蹤記錄

切片

省略

Xrange

(1)代碼對象

        代碼對象是編譯過的Python源代碼片段,它是可執行對象,通過調用内建函數compile()可以得到,然後可以被exec指令或eval()内建函數來執行。

        代碼對象本身不包含任何執行環境資訊,它是使用者自定義函數的核心,在被執行時動态獲得上下文(事實上代碼對象是函數的一個屬性)。一個函數除了有代碼對象屬性以外,還有一些其他函數必須的屬性,包括函數名 文檔字元串 預設參數及全局命名空間等。

(2)幀對象

        幀對象表示Python的執行棧幀。幀對象包含Python解釋器在運作時所需要知道的所有資訊,它的屬性包含下面這些資訊:

指向上一幀的連結

正在被執行的代碼對象

本地及全局名稱空間字典及目前指令等

        每次函數調用産生一個新的幀,每一個幀對象都會相應建立一個C棧幀,用到幀對象的一個地方是跟蹤記錄對象。

(3)跟蹤記錄對象

        當異常發生時,一個包含針對異常的棧跟蹤資訊的跟蹤記錄對象被建立。如果一個異常有自己的處理程式,處理程式就可以通路這個跟蹤記錄對象。

(4)切片對象

        當使用Python擴充的切片文法時,就會建立切片對象。

(5)省略對象

        省略對象用于擴充切片文法中,起記号作用。這個對象在切片文法中表示省略号。類似Null對象None,省略對象有一個唯一的名字Ellipsis:

        它的布爾值始終為True。

(6)Xrange對象

        調用内建函數xrange()會生成一個Xrange對象,xrange()是内建函數range()的兄弟版本,用于需要節省記憶體使用或range()無法完成的超大資料集場合。

5.标準類型操作符

(1)對象值的比較

        比較操作符用來判斷同類型對象的值是否相等,所有的内建類型(前面所說的标準類型和其他内建類型)均支援比較運算,比較運算結果傳回布爾值True或False。

        注意:比較操作是針對對象的值進行的,就就是說比較的是對象的數值而不是對象本身。

        另外提及Python的一個特性,多個操作可以在同一行上進行,求值順序為從左到右:

等價于:

(2)對象身份比較

        在Python中,應該将變量名看成是對象的一個連結,對對象的一個引用,它被指向這個對象,而不是直接指派為該對象。可以使用内建函數id()或關鍵字is和is not來比較兩個對象身份:

相同值,指向相同對象

值相同,指向不同對象

        在Python中,有一個'僅緩存簡單整型'的概念,即對于一些簡單的不可變對象,比如整型對象和字元串對象,Python會先将它們緩存到記憶體中,當需要就直接被引用,而無需建立,可以看下面的例子:

        當然,隻是緩存簡單整型:

        了解起來相對是比較簡單的了。

(3)布爾類型

        按優先級從高到低,主要是:

not

and

or

6.标準類型内建函數

        即用于操作基本肉類的内建函數,如下:

cmp(obj1, obj2):大于傳回負數,小于傳回正數,等于傳回0

repr(obj)或`obj`:傳回一個對象的字元串表示

str(obj):傳回對象适合可讀性好的字元串表示

type(obj):得到一個對象的類型,并傳回相應的類型對象(type對象,與type類型對象不同)

(1)type()

        接受一個對象作為參數,并傳回它的類型,它的傳回值是一個類型對象:

        以<>文法表示的,說明其是一個對象,每個對象都可以實作一個可列印的字元串表示。但對于那些不容易顯示的對象來說,Python會以一個相對标準的格式來表示這個對象,如:<object_something_or_another>,其中提供了對象類别 對象id或位置等資訊。

(2)cmp()

        例子如下:

        比較是在對象之間進行的,不管是标準類型對象還是使用者自定義對象,如果是使用者自定義對象,cmp()會調用該類的特殊方法__cmp__()。

(3)str()和repr()(或``操作符)

        str()和repr()或``用來以字元串方式擷取對象的内容 類型和數值等資訊,作如下說明:

str()

str()函數得到的字元串表示可讀性比較好,适合用于print輸出,大多數情況下都無法将該字元串表示通過eval()求值來得到原來的對象(當然,簡單的就除外了)。

repr()或``

傳回一個對象的“官方”字元串表示,也就是說大多數情況下,都可以将字元串通過eval()求值來得到原來的對象(當然,也有例外的情況)。

        總的來說,repr()輸出對Python比較友好,而str()輸出對使用者比較友好。

(4)type()和isinstance()

type()

type()用于傳回一個對象的類型,它的傳回值是一個類型對象,這些前面已經有所提及,再給出下面的例子:

        type(foo)的輸出之是以會這樣,是因為類就是類型。

isinstance()

如果需要判斷一個對象的類型,可以使用下面的方法:

        當使用isinstance()時,就會友善很多:

        isinstance()第一個參數為一個對象,第二個參數為一個類型對象或一個類型對象的元組(這樣的話,就可以一次與多個類型對象作比較了,省去了多個if-else語句)。

7.類型工廠函數

        因為從Python2.2開始,類和類型就統一了,也就是說,所有的内建類型其實也都是類。而原來的轉換函數int() type() list()等,現在都成了工廠函數,說是函數,實質上他們也是類,調用它們時,實際上就生成了該類型的一個執行個體,就像工廠生産貨物一樣(這就是工廠模式的概念,在做大型程式的開發時,該設計思想很經常會用到)。

        對于Python已給出的工廠函數(實質是類),可以檢視書本P71,下面隻給出作為示範:

int(), long(), float(), complex()

str(), unicode, basestring()

list(), tuple()

8.标準類型的分類

        标準類型:基本内建資料對象原始類型,解釋如下:

基本:是因為這些類型都是Python提供的标準呀核心類型

内建:是因為這些類型是Python預設就提供的

資料:是因為他們用于一般資料存儲

對象:是因為對象是資料和功能的預設抽象

原始:是因為這些類型提供的是最底層的粒度資料存儲

類型:是因為他們就是資料類型

        當然,我們可以對标準類型進行分類,以便于我們更好地了解這些标準類型的特性。

(1)存儲模型

        分類标準:看這種類型的對象能儲存多少個對象。于是會有下面兩種情況:

原子/标量存儲:能儲存單個字面對象的類型

容器存儲:可容納多個對象的類型

        分類如下:

存儲模型

分類

Python類型

标量/原子類型

數值(所有的數值類型),字元串(全部是文字)

容器類型

清單  元組  字典

        其中對于容器對象(也就是清單等這些類型的一個執行個體對象了),它們都能容納不同類型的對象。另外需要注意的是字元串,因為在Python中并沒有“字元”類型的資料結構,是以字元串是一個自我包含的文字類型。

(2)更新模型

        分類标準:值是否可改變。于是會有下面兩種情況:

可變類型:對象的值可以被更新

不可變類型:對象的值不可以被更改

更新模型

可變類型

清單  字典

不可變類型

數字  字元串  元組

        數字或字元串是不可變類型,也許難以了解,但可以看下面的例子:

        也就是說,表面上值是改變了,但實際上是3這個數字對象被丢棄回收,然後建立了一個新的數字對象6。而對于字元串類型,這也充分說明了在Python中是沒有字元類型這一資料結構的。

        但對于可變類型,情況就不一樣了:

(3)通路模型

        分類标準:如何通路存儲的資料。于是會有下面三種情況:

直接存取:非容器類型可以直接通路(對于字元串,會有些特别,是以不會屬于此類)

順序/序列:也就是可以通過使用切片(slice)的方式來進行通路

映射:元素是無序存放的,但可以通過鍵值對的方式進行通路

通路模型

直接通路

數字

順序通路

字元串  清單  元組

映射通路

字典

        雖然字元串是非容器類型,但由于可以使用切片的方式對它進行通路,是以歸類到順序通路。

        将上面的三種分類模型和Python對應的資料結構進行總結,可如下:

标準類型分類

資料類型

标量

不可更改

字元串

清單

容器

可更改

元組

9.不支援的類型

(1)char

        在C語言中會有這種資料類型,但在Python中,則沒有。

(2)指針

        Python的垃圾收集器會替我們管理這些工作,不用擔心。

(3)int short long

        隻需要知道,在Python中,直接使用整型就可以了,因為如果超出了範圍,Python會為我們自動轉換。

(4)float double

        Python的浮點類型實際是C語言的雙精度浮點類型。如果需要更高的精度(處理與金錢相關的資料時),可以使用Python的十進制海戰型類型Decimal,隻需要導入decimal子產品就可以使用。一般情況下,預設的float類型就足夠用了。

        需要強調的是,對象的概念無論是在Python還是在其他的面向對象程式設計語言中,都是十分重要的,如果無法掌握對象,那麼也就不能充分利用面向對象程式設計語言的特性。

本文轉自 xpleaf 51CTO部落格,原文連結:http://blog.51cto.com/xpleaf/1750361,如需轉載請自行聯系原作者