设为首页 收藏本站
查看: 495|回复: 0

[经验分享] Python回顾与整理2:Python对象

[复制链接]

尚未签到

发表于 2018-8-6 09:03:20 | 显示全部楼层 |阅读模式
  0.说明
  说对象是面向对象编程语言最重要的一部分一点也不为过,没有了“对象”,面向对象将无从谈起。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()返回的是一个类型对象,表明42是一个数字类型对象,而<type 'int'>本身也有所属于的类型,可以继续使用type()来查看:
>>> type(type(42))  
<type 'type'>
  <type 'type'>表示<type 'int'>是一个type类型对象,尝试继续使用内建函数type()来作进一步操作:
>>> type(type(type(42)))  
<type 'type'>
  得到的还是type类型对象,于是可以有下面的结论:

  •   所有类型对象的类型都是type,它也是所有Python类型的根和所有Python标准类的默认元类(metaclass)
  •   在Python中,类就是类型,实例是对应类型的对象(类比42的例子,42属于数字类型,它是数字类型构造值后的一个数字对象,或者说42是类int的一个实例对象,因为现在类型就是类)
  (2)None:Python的Null对象
  Python有一个特殊的类型,被称为Null对象或者NoneType,它只有一个值,那就是None
>>> None  
>>> type(None)
  
<type 'NoneType'>
  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:
>>> Ellipsis  
Ellipsis
  
>>> type(Ellipsis)
  
<type 'ellipsis'>
  它的布尔值始终为True。
  (6)Xrange对象
  调用内建函数xrange()会生成一个Xrange对象,xrange()是内建函数range()的兄弟版本,用于需要节省内存使用或range()无法完成的超大数据集场合。
  5.标准类型操作符
  (1)对象值的比较
  比较操作符用来判断同类型对象的值是否相等,所有的内建类型(前面所说的标准类型和其他内建类型)均支持比较运算,比较运算结果返回布尔值True或False。
  注意:比较操作是针对对象的值进行的,就就是说比较的是对象的数值而不是对象本身。
  另外提及Python的一个特性,多个操作可以在同一行上进行,求值顺序为从左到右:
>>> 3 < 4 < 7  
True
  等价于:
>>> 3 < 4 and 4 < 7  
True
  
  (2)对象身份比较
  在Python中,应该将变量名看成是对象的一个链接,对对象的一个引用,它被指向这个对象,而不是直接赋值为该对象。可以使用内建函数id()或关键字is和is not来比较两个对象身份:

  •   相同值,指向相同对象
>>> foo1 = foo2 = 4.3  
>>> a is b
  
True
  
>>> id(a) == id(b)
  
True

  •   值相同,指向不同对象
>>> foo1 = 4.3  
>>> foo2 = 1.3 + 3.0
  
>>> foo1 is foo2
  
False
  
>>> id(foo1)
  
18024120
  
>>> id(foo2)
  
18024048
  在Python中,有一个'仅缓存简单整型'的概念,即对于一些简单的不可变对象,比如整型对象和字符串对象,Python会先将它们缓存到内存中,当需要就直接被引用,而无需创建,可以看下面的例子:
>>> a = 1  
>>> id(a)
  
17953112
  
>>> b = 1
  
>>> id(b)
  
17953112
  
>>> c = 1.0
  
>>> id(c)
  
18024096
  
>>> d = 1.0
  
>>> id(d)
  
18024072
  当然,只是缓存简单整型:
>>> e = 336  
>>> id(e)
  
18554008
  
>>> f = 336
  
>>> id(f)
  
18601504
  理解起来相对是比较简单的了。
  (3)布尔类型
  按优先级从高到低,主要是:

  •   not
  •   and
  •   or
  6.标准类型内建函数
  即用于操作基本肉类的内建函数,如下:

  •   cmp(obj1, obj2):大于返回负数,小于返回正数,等于返回0
  •   repr(obj)或`obj`:返回一个对象的字符串表示
  •   str(obj):返回对象适合可读性好的字符串表示
  •   type(obj):得到一个对象的类型,并返回相应的类型对象(type对象,与type类型对象不同)
  (1)type()
  接受一个对象作为参数,并返回它的类型,它的返回值是一个类型对象:
>>> type(4)  
<type 'int'>
  
>>> type('Hello World!')
  
<type 'str'>
  
>>> type(type(4))
  
<type 'type'>
  以<>语法表示的,说明其是一个对象,每个对象都可以实现一个可打印的字符串表示。但对于那些不容易显示的对象来说,Python会以一个相对标准的格式来表示这个对象,如:<object_something_or_another>,其中提供了对象类别 对象id或位置等信息。
  (2)cmp()
  例子如下:
>>> cmp(1, 2)  
-1
  
>>> cmp(2, 1)
  
1
  
>>> cmp(2, 2)
  
0
  
>>> cmp('abc', 'xyz')
  
-1
  
>>> cmp('abc', 'abc')
  
0
  比较是在对象之间进行的,不管是标准类型对象还是用户自定义对象,如果是用户自定义对象,cmp()会调用该类的特殊方法__cmp__()。
  (3)str()和repr()(或``操作符)
  str()和repr()或``用来以字符串方式获取对象的内容 类型和数值等信息,作如下说明:

  •   str()
      str()函数得到的字符串表示可读性比较好,适合用于print输出,大多数情况下都无法将该字符串表示通过eval()求值来得到原来的对象(当然,简单的就除外了)。
>>> str(1)  
'1'
  
>>> eval(str(1))
  
1
  
>>> str([1, 2, 3])
  
'[1, 2, 3]'
  
>>> eval(str([1, 2, 3]))
  
[1, 2, 3]

  •   repr()或``
      返回一个对象的“官方”字符串表示,也就是说大多数情况下,都可以将字符串通过eval()求值来得到原来的对象(当然,也有例外的情况)。
>>> repr([1, 2, 3])  
'[1, 2, 3]'
  
>>> eval(repr([1, 2, 3]))
  
[1, 2, 3]
  
>>> eval(repr(type(42)))
  
Traceback (most recent call last):
  
  File "<stdin>", line 1, in <module>
  
  File "<string>", line 1
  
    <type 'int'>
  
    ^
  
SyntaxError: invalid syntax
  总的来说,repr()输出对Python比较友好,而str()输出对用户比较友好。
  (4)type()和isinstance()

  •   type()
      type()用于返回一个对象的类型,它的返回值是一个类型对象,这些前面已经有所提及,再给出下面的例子:
>>> class Foo: pass  
...
  
>>> class foo(object): pass
  
...
  
>>> type(Foo)
  
<type 'classobj'>
  
>>> type(foo)
  
<type 'type'>
  type(foo)的输出之所以会这样,是因为类就是类型。

  •   isinstance()
      如果需要判断一个对象的类型,可以使用下面的方法:
>>> from types import IntType  
>>> type(42) == IntType
  
True
  当使用isinstance()时,就会方便很多:
>>> if isinstance(42, (float)):print 'OK'  
...
  
>>> if isinstance(42, (float, int)):print 'OK'
  
...
  
OK
  isinstance()第一个参数为一个对象,第二个参数为一个类型对象或一个类型对象的元组(这样的话,就可以一次与多个类型对象作比较了,省去了多个if-else语句)。
  7.类型工厂函数
  因为从Python2.2开始,类和类型就统一了,也就是说,所有的内建类型其实也都是类。而原来的转换函数int() type() list()等,现在都成了工厂函数,说是函数,实质上他们也是类,调用它们时,实际上就生成了该类型的一个实例,就像工厂生产货物一样(这就是工厂模式的概念,在做大型程序的开发时,该设计思想很经常会用到)。
  对于Python已给出的工厂函数(实质是类),可以查看书本P71,下面只给出作为示范:

  •   int(), long(), float(), complex()
  •   str(), unicode, basestring()
  •   list(), tuple()
  •   type()
  8.标准类型的分类
  标准类型:基本内建数据对象原始类型,解释如下:

  •   基本:是因为这些类型都是Python提供的标准呀核心类型
  •   内建:是因为这些类型是Python默认就提供的
  •   数据:是因为他们用于一般数据存储
  •   对象:是因为对象是数据和功能的默认抽象
  •   原始:是因为这些类型提供的是最底层的粒度数据存储
  •   类型:是因为他们就是数据类型
  当然,我们可以对标准类型进行分类,以便于我们更好地理解这些标准类型的特性。
  (1)存储模型
  分类标准:看这种类型的对象能保存多少个对象。于是会有下面两种情况:

  •   原子/标量存储:能保存单个字面对象的类型
  •   容器存储:可容纳多个对象的类型
  分类如下:
存储模型分类Python类型标量/原子类型数值(所有的数值类型),字符串(全部是文字)容器类型列表  元组  字典  其中对于容器对象(也就是列表等这些类型的一个实例对象了),它们都能容纳不同类型的对象。另外需要注意的是字符串,因为在Python中并没有“字符”类型的数据结构,所以字符串是一个自我包含的文字类型。
  (2)更新模型
  分类标准:值是否可改变。于是会有下面两种情况:

  •   可变类型:对象的值可以被更新
  •   不可变类型:对象的值不可以被更改
  分类如下:
更新模型分类Python类型可变类型列表  字典不可变类型数字  字符串  元组  数字或字符串是不可变类型,也许难以理解,但可以看下面的例子:
>>> a = 3  
>>> id(a)
  
17953064
  
>>> a = 6
  
>>> id(a)
  
17952992
  
>>> x = 'abc'
  
>>> id(x)
  
140407360100672
  
>>> x = 'change'
  
>>> id(x)
  
140407359514784
  也就是说,表面上值是改变了,但实际上是3这个数字对象被丢弃回收,然后创建了一个新的数字对象6。而对于字符串类型,这也充分说明了在Python中是没有字符类型这一数据结构的。
  但对于可变类型,情况就不一样了:
>>> aList = [1, 2, 3]  
>>> id(aList)
  
140407359478888
  
>>> aList.append('change')
  
>>> id(aList)
  
140407359478888
  (3)访问模型
  分类标准:如何访问存储的数据。于是会有下面三种情况:

  •   直接存取:非容器类型可以直接访问(对于字符串,会有些特别,所以不会属于此类)
  •   顺序/序列:也就是可以通过使用切片(slice)的方式来进行访问
  •   映射:元素是无序存放的,但可以通过键值对的方式进行访问
  分类如下:
访问模型分类Python类型直接访问数字顺序访问字符串  列表  元组映射访问字典  虽然字符串是非容器类型,但由于可以使用切片的方式对它进行访问,所以归类到顺序访问。
  将上面的三种分类模型和Python对应的数据结构进行总结,可如下:
标准类型分类数据类型存储模型更新模型访问模型数字标量不可更改直接访问字符串标量不可更改顺序访问列表容器可更改顺序访问元组容器不可更改顺序访问字典容器可更改映射访问  9.不支持的类型
  (1)char
  在C语言中会有这种数据类型,但在Python中,则没有。
  (2)指针
  Python的垃圾收集器会替我们管理这些工作,不用担心。
  (3)int short long
  只需要知道,在Python中,直接使用整型就可以了,因为如果超出了范围,Python会为我们自动转换。
  (4)float double
  Python的浮点类型实际是C语言的双精度浮点类型。如果需要更高的精度(处理与金钱相关的数据时),可以使用Python的十进制海战型类型Decimal,只需要导入decimal模块就可以使用。一般情况下,默认的float类型就足够用了。
  需要强调的是,对象的概念无论是在Python还是在其他的面向对象编程语言中,都是十分重要的,如果无法掌握对象,那么也就不能充分利用面向对象编程语言的特性。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-547355-1-1.html 上篇帖子: python 配置mod_python.publisher 404错误 下篇帖子: python入门(一)pycharm的安装
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表