天天看點

[PYTHON] 核心程式設計筆記之四-Python對象

4.1 Python 對象

Python 使用對象模型來存儲資料

所有的Python對象都擁有三個特性: 身份,類型和值:

身份: 每一個對象都有一個唯一的身份辨別自己,任何對象的身份可以使用内建函數id()來得到,這個值可以認為是該對象的記憶體位址(隻讀)

類型: 對象的類型決定了該對象可以儲存什麼類型的值,可以用内建函數type()檢視python對象的類型(隻讀)

值: 對象表示的資料項

例:

>>> a = 1

>>> id(a)

139464880

>>> type(a)

<type 'int'>

4.1.1 對象屬性

某些Python對象有屬性,值或相關聯的可執行代碼,比如方法(method).Python用點(.)标記法來通路屬性

4.2 标準類型

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

整型

布爾型

長整型

浮點型

複數型

字元串

清單

元祖

字典

4.3 其他内建類型

類型

Null對象(None)

檔案

集合/固定集合

函數/方法

子產品

4.3.1 類型對象和type類型對象

>>> type(42)

<type 'int'>是一個類型對象,它輸出了一個字元串來告訴你它是個int型對象

>>> type(type(42))

<type 'type'>

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

4.3.2 None,Python的Null對象

Python有一個特殊的類型,被稱作Null對象或者NoneType,它隻有一個值,那就是None,它不支援任何運算也沒有任何内建方法

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

注:下列對象的布爾值天生是False

None

False

所有值為零的數:

0(整型)

(浮點型)

0L(長整型)

0.0+0.0j(複數)

""(空字元串)

[](空清單)

()(空元祖)

{}(空字典)

4.4 内部類型

代碼

跟蹤記錄

切片

省略

Xrange

4.4.1 代碼對象

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

4.4.2 幀對象

幀對象表示Python的執行棧幀

4.4.3 跟蹤記錄對象

當代碼出錯,Python就會引發一個異常,如果異常未被捕獲或處理,解釋器就會推出腳本運作,并顯示類似下面的診斷資訊:

Traceback (most recent call last):

 File "<stdin>", line 1, in <module>

TypeError: id() takes exactly one argument (0 given)

4.4.4 切片對象

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

>>> foostr = 'abcde'

>>> foostr[::-1]    

'edcba'

>>> foostr[::-2]    

'eca'

>>> foolist = [123,'xba',342.23,'abc']

>>> foolist[::-1]

['abc', 342.23, 'xba', 123]

4.4.5 省略對象

省略對象用于擴充切片文法中,起記号作用

4.4.6 XRange對象

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

4.5 标準類型運算符

4.5.1 對象值的比較

比較運算符用來判斷同類型對象是否相等

>>> 2 == 2      

True

>>> 2.34 <= 8.32

>>> 5 + 4j >= 2 - 3j

TypeError: no ordering relation is defined for complex numbers

>>> 'abc' == 'xyz'

>>> 'abc' > 'xyz'

>>> 'abc' < 'xyz'

>>> [3,'abc'] == ['abc',3]

>>> [3,'abc'] == [3,'abc']

多個比較操作可以在同一行上進行

>>> 3 < 4 < 7

>>> 4 > 3 == 3

>>> 4 < 3 < 5 != 2 < 7

比較操作時針對對象的值進行的,也就是說比較的是對象的數值而不是對象本身

4.5.2 對象身份比較

将變量名看做對象的一個連結

例1: foo1和foo2指向相同的對象

foo1 = foo2 =4.3

4.3的數字對象被建立,然後這個對象的引用被指派給foo1和foo2,結果就是foo1和foo2指向同一個對象

例2: fool和foo2指向相同的對象

foo1 = 4.3

foo2 = foo1

Python通過傳遞引用來處理對象,foo2就成為原始值4.3的一個新的引用,結果就是foo1和foo2指向同一個對象

例3: foo1和foo2指向不同的對象

foo2 = = 1.3 +3.0

盡管兩個對象儲存的是同樣大小的值,但在系統中儲存的都是兩個獨立對象

每個對象都天生具有一個計數器,記錄它自己的引用次數

a is b 等價于 id(a) == id(b)

對象身份比較運算符擁有同樣的優先級

下面的例子,我們建立了一個變量,然後将第二個變量指向同一個對象

>>> a = [5,'hat',-9.3]

>>> b = a

>>> a is b

>>> a is not b

>>> b = 2.5e-5  

>>> b

2.5e-05

>>> a

[5, 'hat', -9.3]

運算符功能

obj1 is obj2obj1和obj2是同一個對象

obj1 is not obj2obj1和obj2不是同一個對象

注: 整數對象和字元串對象是不可變對象,是以Python會很高效的緩存它們

>>> id (a)

>>> b = 1

>>> id(b)

>>> c = 1.0

>>> id(c)

140438956

>>> d = 1.0

>>> id(d)

140438972

a和b指向了相同的整數對象,但c和d并沒有指向相同的浮點數對象

Python僅緩存簡單整數,因為在Python應用程式中這些小整數會經常被用到,通常緩存的整數範圍是(-1,100)

字元串不會被緩存

4.5.3 布爾類型

布爾邏輯運算符and,or和not都是Python關鍵字,優先級如下

not exprexpr的邏輯非(否)

expr1 and expr2expr1和expr2的邏輯與

expr1 or expr2expr2的邏輯或

>>> x, y = 3.1415926, -1024

>>> x < 5.5

>>> not (x <5.0)

>>> (x < 5.0) or (y > 2.718281828)

>>> (x < 5.0) and (y > 2.718281828)  

>>> not (x is y)

Python支援一個表達式進行多種比較操作,其實這個表達式本質上是由多個隐式的and連接配接起來的多個表達式

>>> 3 < 4 < 7 # same as "( 3 < 4 ) and (4 < 7)"

4.6 标準類型内建函數

函數功能

cmp(obj1,obj2)比較obj1和obj2,根據比較結果傳回整數i:

i<0 if obj1<obj2

i>0 if obj1>obj2

i==0 if obj1 ==obj2

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

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

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

4.6.1 type()

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

>>> type(4)

>>> type('Hello World')

<type 'str'>

>>> type(type(4))

4.6.2 cmp()

内建函數cmp()用于比較兩個對象obj1和obj2

>>> a, b =-4, 12

>>> cmp(a,b)

-1

>>> cmp(b,a)

1

>>> b = -4

>>> a, b ='abc','xyz'

>>> b ='abc'

4.6.3 str()和repr()(及 '' 運算符)

内建函數str和repr()或反引号運算符('')可以以字元串的方式擷取對象的内容,類型,數值屬性等資訊

str()得到的字元串可讀性好,但傳回結果無法用于eval()求值,可用于print語句輸出

repr()得到的字元串可以重新獲得該對象

obj ==eval(repr(obj))

>>> str(4.53-2j)

'(4.53-2j)'

>>> str(1)

'1'

>>> str(2e10)

'20000000000.0'

>>> str([0,5,9,5])

'[0, 5, 9, 5]'

>>> repr([0,5,9,5])

>>> '[0, 5, 9, 5]'

4.6.4 type()和isinstance()

>>> type('')  

>>> s = 'xyz'

>>> type(s)  

>>> type(100)

>>> type(0+0j)

<type 'complex'>

>>> type(0L)  

<type 'long'>

>>> type(0.0)

<type 'float'>

>>> type([])

<type 'list'>

>>> type(())

<type 'tuple'>

>>> type({})

<type 'dict'>

>>> type(type)

>>> class Foo:pass

...

>>> foo = Foo()    

>>> class Bar(object): pass

>>> bar = Bar()

>>> type(Foo)

<type 'classobj'>

>>> type(foo)

<type 'instance'>

>>> type(Bar)

>>> type(bar)

<class '__main__.Bar'>

例4.1 檢查類型(typechk.py)

函數displayNumType()接受一個數值參數,它使用内建函數type()來确認數值的類型

# vi typechk.py

----------------------------

#!/usr/bin/env python

def displayNumType(num):

   print num, 'is',

   if isinstance(num,(int,long,float,complex)):

       print 'a number of type:',type(num).__name__

   else:

       print 'not a number at all!!'

displayNumType(-69)

displayNumType(9999999999999999999999999999999999999L)

displayNumType(98.6)

displayNumType(-5.2+1.9j)

displayNumType('xxx')

# python typechk.py

-----------------------

-69 is a number of type: int

9999999999999999999999999999999999999 is a number of type: long

98.6 is a number of type: float

(-5.2+1.9j) is a number of type: complex

xxx is not a number at all!!

4.7 類型工廠函數

Python 2.2同意了類型和類,所有内建類型現在也都是類,在這個基礎上,原來所謂内建轉換函數像int(),type(),list()等等,現在都成了工廠函數,也就是說雖然他們看上去有點象函數,實際上他們是類,當你調用他們時,實際上市生成了該類型的一個執行個體

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

str(),unicode(),basestring()

list(),tuple()

type()

dict()

   bool()

   set(),frozenset()

   lbject()

   classmethod()

staticmethod()

super()

property()

file()

4.8 标準類型的分類

基本,是指這些類型都是Python提供的标準或核心類型

内建,是由于這些類型是Python預設就提供的

資料,因為他們呢用于一般資料存儲

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

原始,提供最底層的粒度資料存儲

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

4.8.1 存儲模型

存儲模型

分類Python類型

标量/原子類型數值(所有數值類型),字元串(全部是文字)

容器類型清單,元祖,字典

4.8.2 更新模型

可變類型清單,字典

不可變類型數字,字元串,元祖

加上id()調用,就會清楚看到對象實際上已經被替換了:

>>> x = 'Python numbers and strings'

>>> print id(x)

139797637900016

>>> x = 'are immutable?!? What gives?'

139797637889960

>>> i = 0

>>> print id(i)

16988128

>>> i = i + 1

16988104

注:傳回值與該對象當時配置設定的記憶體位址相關,是以不同機器都不同

>>> aList = ['ammonia',83,85,'lady']

>>> aList

['ammonia', 83, 85, 'lady']

>>> aList[2]

85

>>> id(aList)

139797637819280

>>> aList[2] = aList[2] + 1

>>> aList[3] = 'stereo'

['ammonia', 83, 86, 'stereo']

>>> aList.append('gaudy')

>>> aList.append(aList[2] + 1)

['ammonia', 83, 86, 'stereo', 'gaudy', 87]

注: 清單的值無論怎麼改變,清單的ID始終保持不變

4.8.3 通路模型

在通路模型中共有三種通路模式:

直接存取,順序和映射

以通路模型為标準的類型分類

通路模型

直接通路數字

順序通路字元串,清單,元祖

映射通路字典

标準類型分類

資料類型  存儲模型  更新模型  通路模型

數字  Scalar    不可更改  直接通路

字元串    Scalar    不可更改  順序通路

清單  Container 可更改    順序通路

元祖  Container 不可更改  順序通路

字典  Container 可更改    映射通路

4.9 不支援的類型

char 或 byte

指針

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