返回介绍

Python 表达式操作符

发布于 2024-01-29 22:24:17 字数 4060 浏览 0 评论 0 收藏 0

表达式是处理数字的最基本的工具。当一个数字(或其他对象)与操作符相结合时,Python执行时将计算得到一个值。在Python中,表达式是使用通常的数学符号和操作符号写出来的。例如,让两个数字X和Y相加,写成X+Y,这就会告诉Python,对名为X和Y的变量值应用+的操作。这个表达式的结果就是X与Y的和,也就是另一个数字对象。

表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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文