2015/8/28 Python基础(2):对象

Python用对象模型来存储数据。构造任何类型的值都是一个对象。
Python对象都有是三个特性:身份,类型和值

身份是每个对象的唯一身份标识。任何对象都可以用内建函数id()来得到身份。如:

>>> s = 1
>>> id(s)
38249176

身份可以认为是该对象的地址。

类型是数据以何种方式保存,可以进行怎样的操作,遵循怎样的规则。可以使用内建函数type()来查看。

值就是对象的数据项。

上面三个特性在对象创建时被赋值,除值以外其他特性都是只读。对象的类型是可以改变的,但对于初学者不建议这么做

Python是用点标记法来访问属性的,属性包括对象的名字等等,最常用的属性是函数和方法,不过有一些也有数据属性。含有数据属性的对象包括(不限于):类、类实例、模块、复数和文件

Python的标准类型有:数字、整型、布尔、长整型、浮点、复数、字符串、列表、元组和字典。同时还有如下内建类型:类型(对,类型本身是一种类型)、Null对象、文件、集合、函数/方法、模块、类。

类型也是一种对象,因为对象的一系列固有行为和特性需要事先定义,我们用类型这种对象来保存这些信息。
用内建函数type()可以得到特定对象的类型信息

>>> type(7)
<type ‘int‘>

这里输出了<type ‘int‘>,其实并不是简单告诉这是一个整数这样的字符串,而是一个类型对象,这个对象会输出一个字符串来告诉你他是一个对象。我们可以这样测试它

>>> type(type(7))

如果这只是一个字符串,它会显示<type ‘str‘>如果是对象类型,它会显示<type ‘type‘>

结果是

>>> type(type(7))
<type ‘type‘>

None,Null对象

这是一个特殊的类型,它只有一个值是None,类似于C的void,没有任何内建方法,没有有用的属性,布尔值总是False

同时还有一些用类实现的内部类型,这里暂不赘述。

标准类型运算符
对象值的比较
比较运算符来判断同类型的对象是否相等,返回True或False。运算符有== 、<= 、 >=。多个比较可以在同一行里进行,这一点和C不同。比较的顺序式从左到右

>>> 3 < 4 < 5
True
>>> 3 < 5 < 4
False

大多数语言中会写成这种形式

>>> 3 < 4 and 4 < 5
True
>>> 3 < 5 and 5 < 4
False

同时,可以用如下的写法,数学中一般不写

>>> 3 < 5 > 4
True

对象身份的比较
这是对值比较的补充,Python也支持对象本身的比较。
用的是如下的语句

a is b

它是用于比较a、b两个变量是否是指向同样的对象的。和a == b不相同。

a is b等价于
id(a) == id(b)
有如下的代码

>>> foo1 = 2.0
>>> foo2 = 1.0 + 1.0
>>> foo1 == foo2
True
>>> foo1 is foo2
False
>>> foo1 = 2.0
>>> foo2 = 2.0
>>> foo1 is foo2
False
>>> foo2 = foo1
>>> foo1 is foo2
True
>>> foo3 = 2
>>> foo4 = 1 + 1
>>> foo3 is foo4
True

这里可以看到foo1和foo2的值是相等的,但它们身份不相等。也就是说并不是来自同一个引用。说明在内部存储它们时,是各自创建了两个对象然后引用的。

然后还能看到,当我同时给foo1和foo2赋值2.0后,它们并不相等。是创造了两个对象,只有将foo1直接赋值给foo2才能使它们指向同一个对象。
从此可以理解Python内部的赋值方式,每一个值进行新对象创造再引用给变量。
但是,如果是对整数,结果就不同。书里说明:
整数对象和字符串对象是不可变对象,所以Python 会很高效的缓存它们。这会造成我们认为Python 应该创建新对象时,它却没有创建新对象的假象。
也就是说,整型和浮点型出现不同的缘故是因为Python高效地缓存了它们。不过这个缓存是有范围的,一定要小心使用。

标准类型内建函数
函数 功能
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 对象

repr()返回的是一个对象的“官方”字符串表示, 也就是说绝大多数情况下可以通过求值运算(使用eval()内建函数)重新得到该对象,但str()则有所不同。str() 致力于生成一个对象的可读性好的字符串表示,它的返回结果通常无法用于eval()求值, 但很适合用于 print 语句输出。也就是说 repr() 输出对 Python 比较友好, 而str()的输出对人比较友好。虽然如此,很多情况下这三者的输出仍然都是完全一样的。所谓的对Python友好和对人友好将会在数值这一部分中提到。

类型工厂函数
Python2.2统一了类型和类,所有的类型也都是类,原来的内建转换函数如type(),int()都成了工厂函数,也就是说虽然看上去像函数,但实际上是类。调用时是生成了一个类型的实例。
关于类部分,由于本人学习的C语言里没有过多涉及,等到学习到类部分再做笔记。

存储模型里,
有存储一个或多个值的标量/原子类型,如数值和字符串。
有容器类型,如列表、元组、字典。
因为Python没有char类型,所以字符串是一个自我包含的文字类型,不是C中和数组相同的情况。

更新模型,
对象创建后,可以更新值的是更新模型,不允许更改的是不可变对象。列表和字典是可变模型,数字、字符串、元组是不可变模型。
这里面存在理解偏差,数值和字符串变量可换,但对象不可更新,每次变换是重新创造了对象。
也就是说每次变换后id()的值都会发生变化。而字典和列表,改变值本身,id()始终不变。

访问模型,
这种分类是区分数据类型的首要类型。按照访问我们存储的数据的方式来分类。有三种访问方式:直接存取、顺序、映射。
直接存取 数字
顺序访问 字符串、列表、元组
映射访问 字典
直接存取不赘述,顺序访问的是序列类型,就是元素从0开始索引顺序访问,一次可以访问一个或者多个元素。
映射类型类似序列类型的索引属性,但不适用地址偏移量取值,元素是无序存放的,通过一个唯一的key来访问。是键-值集合

分类数据类型的原因一是,Python提供的高级数据,我们要将原始的类型和功能强大的扩展类型区分开,所以需要了解分类。二是帮助我们搞清每种类型的特点。
通过不同方面来分类的原因是这些数据结构本身的关系是复杂的,需要我们多次分清晰脉络,让我们对类型了解更深。

Python没有的类型
char或byte。Python没有8位的整数。可以用长度为1的字符串替代。
指针。Python帮助程序员管理内存,所以不用访问指针。通过id()得到的值很接近地址,但是不能操作,所以指针也就没有用。
没有短整长整的区别,让程序员更专注于该干的事。
也没有单双精度的浮点类型。让事情更简单。

时间: 2025-01-12 11:12:19

2015/8/28 Python基础(2):对象的相关文章

python基础——函数对象和闭包

关于函数对象和闭包 闭包(closure)是函数式编程的重要的语法结构.不同的语言实现闭包的方式不同.Python以函数对象为基础,为闭包这一语法结构提供支持的 (我们在特殊方法与多范式中,已经多次看到Python使用对象来实现一些特殊的语法).Python一切皆对象,函数这一语法结构也是一个对象.在函数对象中,我们像使用一个普通对象一样使用函数对象,比如更改函数对象的名字,或者将函数对象作为参数进行传递. 一.函数对象: 1.函数可以当参数传递 示例: #把函数当成参数传递 def foo()

2015/9/20 Python基础(16):类和实例

面向对象编程编程的发展已经从简单控制流中按步的指令序列进入到更有组织的方式中,依靠代码块可以形成命名子程序和完成既定的功能.结构化的或过程性编程可以让我们把程序组织成逻辑快,以便重复或重用.创造程序的过程变得更具逻辑性:选出的行为要符合规范,才可以约束创建的数据.迪特尔父子认为结构化编程是“面向行为”的,因为事实上,即使没有任何行为的数据也必须“规定”逻辑性.然而,如果我们能对数据加上动作呢?如果我们所创建和编写的数据片段,是真实生活中实体的模型,内嵌数据体和动作呢?我们通过一系列已定义的接口(

2015/10/9 Python基础(21):可调用和可执行对象

在Python中有多种运行外部程序的方法,比如,运行操作系统命令或另外的Python脚本,或执行一个磁盘上的文件,或通过网络来运行文件.这完全取决于想要干什么.特定的环境包括: 在当前脚本继续运行 创建和管理子进程 执行外部命令或程序 执行需要输入的命令 通过网络来调用命令 执行命令来创建需要处理的输出 执行其他的Python脚本 执行一系列动态生成的Python语句 导入Python模块 Python中,内建和外部模块都可以提供上述各种功能.程序员得根据实现的需要,从这些模块中选择合适的处理方

2015/9/29 Python基础(20):类的授权

类的授权 1.包装包装在Python编程世界中时经常会被提到的一个术语.它是一个通用的名字,意思是对一个已存在的对象进行包装,不管它是数据类型,还是一段代码,可以是对一个已存在的对象,增加新的,删除不要的,或者修改其他已存在的功能.在Python2.2以前,从Python的标准类型子类化或派生类都是不允许的,即使你现在可以这么做,这种做法也并不多.你可以包装任何类型作为一个类的核心成员,以使新对象的行为模仿你想要的数据类型中已存在的行为,并且去掉你不希望存在的行为:它可能会要做一些额外的事情.这

2015/9/15 Python基础(12):模块和包

模块是用来组织 Python 代码的方法,而包则是用来组织模块的. 当代码量很大时,我们一般会把代码分成几个有组织的代码段,然后每个代码段之间有一定的联系.代码单之间是共享的,所以Python允许调入一个模块,允许使用其他模块的属性利用之前的工作成果,实现代码重用.那些自我包含并且有组织的代码片段就是模块(module),将其他模块中属性附加到你的模块中的操作较导入(import) 模块是逻辑上的说法,而它们在物理层是一个个独立的文件,模块的文件名就是模块的名字加拓展名.py.与其他可以导入类的

2015/9/21 Python基础(17):绑定和方法调用

绑定和方法调用现在我们需要再次阐述Python中绑定(binding)的概念,它主要与方法调用相关联.方法是类内部定义的函数,这意味着方法是类属性而不是实例属性.其次,方法只有在其所属的类拥有实例时,才能被调用.当存在一个实例时,方法才被认为是绑定到那个实例了,没有实例时,方法就是未绑定的.任何一个方法定义中都有一个参数是变量self.它表示调用此方法的实例对象. 核心笔记:self变量用于在类实例方法中引用方法所绑定的实例.方法的实例在任何方法调用中总是作为第一参数传递的,self代表方法的实

2015/9/22 Python基础(18):组合、派生和继承

一个类被定义后,目标就是把它当成一个模块来使用,并把这些对象嵌入到你的代码中去,同其他数据类型及逻辑执行流混合使用.有两种方法可以在你的代码中利用类.第一种是组合,就是让不同的类混合并加入到其他类中,来增强功能和代码重用性.你可以在一个大点的类中创建你自己的类的实例,实现一些其他属性和方法来增强原来的类对象.另一种是派生,通过子类从基类继承核心属性,不断地派生扩展功能实现. 组合举例来说,我们想对之前做过的地址本类作加强性设计.如果在设计的过程中,为names.addresses等创建了单独的类

2015/9/17 Python基础(13):函数

函数是对程序逻辑进行结构化或过程化的一种编程方法. Python的函数返回值当什么也不返回时,返回了None和大多数语言一样,Python返回一个值或对象.只是在返回容器对象时,看起来像返回多个对象.这样在操作的时候显得很灵活,虽然它本质上只是反悔了一个对象. 调用函数我们用一对圆括号电泳函数.任何输入的参数都应该放在括号中. 关键字参数这个概念是针对函数调用的,比如我们有这样的函数 def fun(value, count): fun_suite 我们可以标准调用: fun(12,20) 也可

2015/9/9 Python基础(10):文件和输入输出

文件对象文件对象不仅可以用来访问普通的磁盘文件,而且也可以访问其它任何类型抽象层面上的“文件”.一旦设置了合适的“钩子”,你就可以访问文件类型接口的其它对象,就好像访问的是普通文件一样.文件对象的处理要以来很多内建函数,还有很多函数会返回文件对象或者是类文件对象.进行这种轴向处理的主要原因是许多输入/输出数据结构更趋向于使用通用的接口.这样就可以在程序行为和实现上保持一致性.文件只是连续的字节序列,数据传输经常会用到字节流,无论字节流是由单个字节还是大块数据组成. 文件内建函数[open()和f