[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'>


<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

True

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

Traceback (most recent call last):

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

TypeError: no ordering relation is defined for complex numbers

>>> 'abc' == 'xyz'

False

>>> 'abc' > 'xyz'

False

>>> 'abc' < 'xyz'

True

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

False

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

True


多个比较操作可以在同一行上进行


>>> 3 < 4 < 7

True

>>> 4 > 3 == 3

True

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

False


比较操作时针对对象的值进行的,也就是说比较的是对象的数值而不是对象本身


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指向不同的对象

foo1 = 4.3

foo2 = = 1.3 +3.0


尽管两个对象保存的是同样大小的值,但在系统中保存的都是两个独立对象


每个对象都天生具有一个计数器,记录它自己的引用次数


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


对象身份比较运算符拥有同样的优先级

下面的例子,我们创建了一个变量,然后将第二个变量指向同一个对象

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

>>> b = a

>>> a is b

True

>>> a is not b

False

>>> b = 2.5e-5  

>>> b

2.5e-05

>>> a

[5, 'hat', -9.3]

>>> a is b

False

>>> a is not b

True


运算符功能

obj1 is obj2obj1和obj2是同一个对象

obj1 is not obj2obj1和obj2不是同一个对象


注: 整数对象和字符串对象是不可变对象,所以Python会很高效的缓存它们


>>> a = 1

>>> id (a)

139464880

>>> b = 1

>>> id(b)

139464880

>>> 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

True

>>> not (x <5.0)

False

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

True

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

False

>>> not (x is y)

True


Python支持一个表达式进行多种比较操作,其实这个表达式本质上是由多个隐式的and连接起来的多个表达式


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

True


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 'int'>

>>> type('Hello World')

<type 'str'>

>>> type(type(4))

<type 'type'>


4.6.2 cmp()


内建函数cmp()用于比较两个对象obj1和obj2


>>> a, b =-4, 12

>>> cmp(a,b)

-1

>>> cmp(b,a)

1

>>> b = -4

>>> cmp(a,b)

0

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

>>> cmp(a,b)

-1

>>> cmp(b,a)

1

>>> b ='abc'

>>> cmp(a,b)

0


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]'

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

'[0, 5, 9, 5]'


4.6.4 type()和isinstance()


>>> type('')  

<type 'str'>

>>> s = 'xyz'

>>> type(s)  

<type 'str'>

>>> type(100)

<type 'int'>

>>> 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)

<type 'type'>


>>> class Foo:pass

...

>>> foo = Foo()    

>>> class Bar(object): pass

...

>>> bar = Bar()

>>> type(Foo)

<type 'classobj'>

>>> type(foo)

<type 'instance'>

>>> type(Bar)

<type 'type'>

>>> 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 更新模型


存储模型

分类Python类型

可变类型列表,字典

不可变类型数字,字符串,元祖


加上id()调用,就会清楚看到对象实际上已经被替换了:


>>> x = 'Python numbers and strings'

>>> print id(x)

139797637900016

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

>>> print id(x)

139797637889960

>>> i = 0

>>> print id(i)

16988128

>>> i = i + 1

>>> print id(i)

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'

>>> aList

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

>>> id(aList)

139797637819280

>>> aList.append('gaudy')

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

>>> aList

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

>>> id(aList)

139797637819280


注: 列表的值无论怎么改变,列表的ID始终保持不变


4.8.3 访问模型

在访问模型中共有三种访问模式:

直接存取,顺序和映射


以访问模型为标准的类型分类


访问模型

分类Python类型

直接访问数字

顺序访问字符串,列表,元祖

映射访问字典


标准类型分类


数据类型  存储模型  更新模型  访问模型

数字  Scalar    不可更改  直接访问

字符串    Scalar    不可更改  顺序访问

列表  Container 可更改    顺序访问

元祖  Container 不可更改  顺序访问

字典  Container 可更改    映射访问


4.9 不支持的类型


char 或 byte


指针


你可能感兴趣的:(python,对象,核心编程笔记)