- 译者序
- 前言
- 第1章 问答环节
- 第2章 Python 如何运行程序
- 第3章 如何运行程序
- 第4章 介绍 Python 对象类型
- 第5章 数字
- 第6章 动态类型简介
- 第7章 字符串
- 第8章 列表与字典
- 第9章 元组、文件及其他
- 第10章 Python 语句简介
- 第11章 赋值、表达式和打印
- 第12章 if 测试和语法规则
- 第13章 while 和 for 循环
- 第14章 迭代器和解析,第一部分
- 第15章 文档
- 第16章 函数基础
- 第17章 作用域
- 第18章 参数
- 第19章 函数的高级话题
- 第20章 迭代和解析,第二部分
- 第21章 模块:宏伟蓝图
- 第22章 模块代码编写基础
- 第23章 模块包
- 第24章 高级模块话题
- 第25章 OOP:宏伟蓝图
- 第27章 更多实例
- 第28章 类代码编写细节
- 第29章 运算符重载
- 第30章 类的设计
- 第31章 类的高级主题
- 第32章 异常基础
- 第34章 异常对象
- 第35章 异常的设计
- 第36章 Unicode 和字节字符串
- 字符串基础知识
- Python 的字符串类型
- 文本和二进制文件
- Python 3.0 中的字符串应用
- 转换
- 编码 Unicode 字符串
- 编码非ASCII文本
- 编码和解码非ASCII文本
- 其他 Unicode 编码技术
- 转换编码
- 在 Python 2.6 中编码 Unicode 字符串
- 源文件字符集编码声明
- 使用 Python 3.0 Bytes 对象
- 序列操作
- 创建 bytes 对象的其他方式
- 混合字符串类型
- 使用 Python 3.0(和 Python 2.6)bytearray 对象
- 使用文本文件和二进制文件
- Python 3.0 中的文本和二进制模式
- 类型和内容错误匹配
- 使用 Unicode 文件
- 在 Python 3.0 中处理 BOM
- Python 2.6 中的 Unicode 文件
- Python 3.0 中其他字符串工具的变化
- Struct二进制数据模块
- pickle对象序列化模块
- XML解析工具
- 本章小结
- 本章习题
- 习题解答
- 第37章 管理属性
- 第38章 装饰器
- 第39章 元类
- 附录A 安装和配置
- 附录B 各部分练习题的解答
- 作者介绍
- 封面介绍
Python 表达式操作符
表5-2列举了Python所有的操作符表达式。有许多是一看就懂的。例如,支持一般的数学操作符(+、-、*、/等)。如果你曾经使用过其他语言的话,其中一些操作符应该很眼熟:%是计算余数操作符;<<执行左移位,&计算位与的结果等。其他的则更Python化一些,并且不全都具备数值特征。例如,is操作符测试对象身份(也就是内存地址,严格意义上的相等),lambda创建匿名函数。
由于本书既介绍Python 2.6又涉及Python 3.0,这里给出关于表5-2中的操作符的版本差异和最新添加:
·在Python 2.6版中,值不相等可以写成X!=Y或X<>Y。在Python 3.0之中,后者会被移除,因为它是多余的。值不相等测试使用X!=Y就行了。
·在Python 2.6中,一个后引号表达式'X'和repr(X)的作用相同,转换对象以显示字符串。由于其不好理解,Python 3.0删除了这个表达式,使用更容易理解的str和repr内置函数,本章后面的“数字显示的格式”小节介绍了这点。
·在Python 2.6和Python 3.0中,floor除法表达式(X//Y)总是会把余数小数部分去掉。在Python 3.0中,X/Y表达式执行真正的除法(保留余数)和Python 2.6中的传统除法(截除为整数)。参见后面的“除法:传统除法、Floor除法和真除法”一节。
·列表语法([...])用于表示列表常量或列表解析表达式。后者是执行隐性循环,把表达式的结果收集到新的列表中。参见第4章、第14章和第20章中的实例。
·(...)语法用于表示元组和表达式,以及生成器表达式,后者是产生所需结果的列表解析的一种形式,而不是构建一个最终的列表。参见第4章和第20章的示例。在所有3种结构中,圆括号有时候会省略。
·{...}语法表示字典常量,并且在Python 3.0中可以表示集合常量以及字典和集合解析。参见本章、第4章、第8章、第14章和第20章中关于集合的示例。
·yield和三元选择表达式在Python 2.5及其以后的版本中可用。前者返回生成器中的send(...)参数,后者是一个多行if语句的缩写形式。如果yield不是单独地位于一条赋值语句的右边的话,需要用圆括号。
·比较操作符可以连续使用:X<Y<Z的结果与X<Y and Y<X相同。参见本书后面的“比较:一般的和连续的”小节。
·在最近的Python中,分片表达式X[I:J:K]等同于用一个分片对象索引:X[slice(I,J,K)]。
·在Python 2.X,混合类型的广义比较是允许的(把数字转换为一个普通类型,并且根据类型名称来排列其他的混合类型)。在Python 3.0中,非数字的混合类型的大小比较是不允许的,并且会引发异常,这包括按照代理排序。
·在Python 3.0中,对字典的大小比较也不再支持(尽管支持相等性测试);比较sorted(dict.items())是一种可能的替代。
在后面,我们将看到表5-2中的大多数操作符的应用;但是,首先,我们需要快速浏览一下这些操作符可能组合为表达式的方式。
混合操作所遵循的操作符优先级
就像大多数语言一样,在Python中,将表5.2中的操作符表达式像字符串一样结合在一起就能编写出很多较复杂的表达式。例如,两个乘法之和可以写成变量和操作符的结合:
那么,如何让Python知道先进行哪个操作呢?这个问题的答案就在于操作符的优先级。当编写含有一个操作符以上的表达式时,Python将按照所谓的优先级法则对其进行分组,这个分组决定了表达式中各部分的计算顺序。表5-2根据操作符的优先级来排序:
·在表5-2中,表的操作符中越靠后的优先级越高,因此在混合表达式中要更加小心。
·表5-2中位于同一行的表达式在组合的时候通常从左到右组合(除了幂运算,它是从右向左组合的,还有比较运算,是从左到右连接的)。
例如,计算表达式X+Y*Z,Python首先计算乘法(Y*Z),然后将其结果与X相加,因为“*”比“+”优先级高。类似地,在这一节的最初那个例子中,两个乘法(A*B和C*D)将会在它们的结果相加之前进行。
括号分组的子表达式
如果用括号将表达式各部分进行分组的话,就可以完全忘掉优先级的事情了。当使用括号划分子表达式的时候,就会超越Python的优先级规则。Python总会先行计算括号中的表达式,然后再将结果用在整个表达式中。
例如,表达式X+Y*Z写成下边两个表达式中的任意一个以此来强制Python按照你想要的顺序去计算表达式:
在第一种情况下,“+”首先作用于X和Y,因为这个子表达式是包含在括号中的。在第二种情况下,首先使用“*”(即使这里没括号也会这样)。一般来说,在一个大型表达式中增加括号是个很好的方法,它不仅仅强制按照你想要的顺序进行计算,同时也增加了程序可读性。
混合类型自动升级
除了在表达式中混合操作符以外,也能够混合数字的类型。例如,可以把一个整数与一个浮点数相加:
但是这将引出另一个问题:它们的结果是什么类型?是整数还是浮点数?答案很简单,特别是如果你有使用其他语言经验的话:在混合类型的表达式中,Python首先将被操作的对象转换成其中最复杂的操作对象的类型,然后再对相同类型的操作对象进行数学运算。如果你使用过C语言,你会发现这个行为与C语言中的类型转换是很相似的。
Python是这样划分数字类型的复杂度的:整数比浮点数简单,浮点数比复数简单。所以,当一个整数与浮点数混合时,就像前边的那个例子,整数首先会升级转为浮点数的值,之后通过浮点数的运算法则得到浮点数的结果。类似地,任何混合类型的表达式,其中一个操作对象是更为复杂的数字,则会导致其他的操作对象升级为一个复杂的数字,使得表达式获得一个复杂的结果。(在Python 2.6中,一般整数的值太大了以至于一般整数存储不下的时候,它会转换为长整数;在Python 3.0中,整数完全是长整数的形式)。
可以通过手动调用内置函数来强制转换类型:
然而,通常是没有必要这样做的。因为Python在表达式中自动升级为更复杂的类型,其结果往往就是你所想要的。
再者,要记住所有这些混合类型转换仅仅在将数字类型(例如,一个整数和一个浮点数)混合到一个表达式中的时候才适用,这包括那些使用数字和比较操作符的表达式。一般来说,Python不会在其他的类型之间进行转换。例如,一个字符串和一个整数相加,会产生错误,除非你手动转换其中某个的类型。请注意第7章学习有关字符串的内容时将要看到的一个例子。
注意:在Python 2.6中,非数字混合类型也可以比较,但是,不执行转换(混合类型比较根据一个确定但任意的规则)。在Python 3.0中,非数字混合类型的比较是不允许的,并且会引发异常。
预习:运算符重载
尽管我们目前把注意力集中在内置的数字类型上,要留心所有的Python操作符可以通过Python的类或C扩展类型被重载(即实现),让它也能工作于你所创建的对象中。例如,用类编写的对象代码也许可以使用+表达式做加法或连接,以及使用[i]表达式进行索引等。
再者,Python自身自动重载了某些操作符,能够根据所处理的内置对象的类型而执行不同的操作。例如,“+”操作符应用于数字时是在做加法,而用于字符串或列表这样的序列对象时是在做合并运算。实际上,“+”应用在定义的类的对象上可以进行任何运算。
就像我们在前一章介绍过,这种特性通常称作多态。这个术语指操作的意义取决于所操作的对象的类型。第16章将会复习这个概念,因为在那时这已经成了更显著的特性了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论