探索Python,第1部分:Python的内置数值类型
PiscesSTAR
|
1#
PiscesSTAR 发表于 2008-06-27 12:57
探索Python,第1部分:Python的内置数值类型转载:http://www.ibm.com/developerworks/cn/opensource/os-python1/index.html Python入门,功能强大的面向对象脚本语言 级别:初级 Robert J. Brunner (rb@ncsa.uiuc.edu), 研究科学家 2005 年 6 月 06 日 Python编程语言具有很高的灵活性,它支持多种编程方法,包括过程化的、面向对象的和函数式的。但最重要的是,在Python中编写程序是件令人愉悦的事。该语言对开发进程有支持作用,决不会妨碍它。本文是关于Python编程系列文章的第一篇,主要介绍Python及其内置数值类型。 Python是一种敏捷的、动态类型化的、极富表现力的开源编程语言,可以被自由地安装到多种平台上(参阅参考资料)。Python代码是被解释的。如果您对编辑、构建和执行循环较为熟悉,则Python代码对您来说更简单。但是,请不要搞错:Python可以是简单的脚本,也可以是大型的复杂程序。事实上,Python解释器的最大特点是鼓励探索和简化学习过程。如果您想证明这一点,请使用Python编写著名的 Hello World! 程序: 1. 启动Python解释器。在UNIX系统(包括Mac OS X)中,启动解释器通常包括在命令提示行键入 python;在Microsoft® Windows®系统中,启动Python命令shell。 2. 在Python提示行中,在三个大于号(>>>)标志后输入 print 'Hello World!',然后按 Enter。 3. 完成:没有第三步了。清单1显示了此命令的输出。 清单1. 用Python编写的"Hello World"的输出 rb% python Python 2.4 (#1, Mar 29 2005, 12:05:39) [GCC 3.3 20030304 (Apple Computer, Inc. build 1495)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> print 'Hello World!' Hello 您可以看到,我使用的是运行于Apple OS X系统上的Python V2.4。但是,不管操作系统是什么,基本原理都是一样的,而且在本例中,所用的是Python的哪一个实际版本也无所谓。我虽然不了解您,但是此Hello World! 练习比我学过的C、C++甚至Java™ 语言的对应练习容易多了。这种简单性就是使用Python解释器的主要优点之一。开发人员可以快速试验一个想法、研究一种对象属性或不同算法,而无需编译、执行和测试任何代码。 Python类型层次结构 从其他语言过渡到Python编程语言时需要学习的最重要的课程之一是,Python中的每样东西都是对象。这一点可能并没有什么特别之处,尤其是对于熟悉面向对象的语言(如C++、Java或C#)的人来说。然而,Python的面向对象原理与其他语言不同,主要表现在两个方面:第一,Python中的所有数据值都被封装在相关对象类中。第二,Python程序中的所有东西都是可以从程序访问的对象,即使是您编写的代码也不例外。 大多数流行的编程语言都有多个内置的数据类型,在这一方面Python也一样。例如,C编程语言具有整型和浮点类型。由于谱系相同,Java语言和C#具有内置类型也不足为奇。这意味着在C程序中,可以编写int i = 100来创建和初始化整型变量。在Java和C#中,此方法也是可能的,而且使用它们的自动装箱功能,在需要时这两种语言还可以把这种简单的内置类型转换为Integer对象。 另一方面,Python不包含像int这样的简单类型——只有对象类型。如果Python中需要整数值,将整数赋值给相应变量(如i = 100)即可。在后台,Python将创建一个整数对象,并将对新对象的引用赋值给变量。问题的关键是:Python是一种动态类型化语言,所以无需声明变量类型。事实上在单个程序中,变量的类型是可以改变(多次)的。 一种直观演示动态类型化工作方式的简单方法是,设想单个名为PyObject的基类,让Python中的所有其他对象类型都继承它。在这一模型中,您创建的所有变量都将引用在总的类层次结构中创建的对象。如果您还让PyObject类记录曾创建并分配给变量的子类的实际类型或名称,则Python程序可正确确定程序执行过程中需要采取的步骤。 上一段描述Python的面向对象的模型图像是对Python的实际工作方式很好的模拟。除此之外,Python还可以使用类型函数来简化对变量类型的确定。(本例还介绍如何使用带有#字符的内联注释。) 清单2. 演示Python简单类型 >>> i = 100 # Create an int object whose value is 100 >>> type(i) >>> f = 100.0 >>> type(f) 可以将PyObject类之下的所有Python类划分为Python运行时解释器可以使用的四个主要类别: * 简单类型 —— 基本构建块,如int和float。 * 容器类型 —— 保存其他对象。 * 代码类型 —— 封装Python程序的元素。 * 内部类型 —— 程序执行期间使用的类型。 到本系列结束时,我会把所有不同类别都介绍给大家。但是在这第一篇文章中,我重点介绍简单类型。 简单类型 Python有五个内置的简单类型:bool、int、long、float和complex。这些类型是不可变的,就是说整数对象一旦创建,其值便不可更改。相反,系统将创建新的简单类型对象并将其赋值给变量。通过Python id函数,可以查看基本PyObject标识的变更方式: 清单3. 使用Python id函数 >>> i = 100 >>> id(i) 8403284 >>> i = 101 >>> id(i) 8403296 此方法看似容易丢失对象,会导致内存泄漏。但是,Python像C#和Java一样,使用了垃圾回收功能,以释放用于保存不再引用的对象的内存,如上例中用于保存100的整数对象。 布尔类型 Python中最简单的内置类型是bool类型,该类型包括的对象仅可能为True或False: 清单4. bool类型 >>> b = True >>> type(b) >>> id(b) 1041552 因为只有两个可能值,所以布尔类型是惟一的。Python解释器提供这仅有的(也是必需的)两个bool对象:True和False。在任何时候,在Python程序需要这些对象时,变量只能相应地引用其中一个值。清单5显示bb变量如何具有同一个id,不管您直接赋予它b变量的值还是直接赋予它True对象。 清单5. bb变量的值 >>> b = True >>> id(b) 1041552 >>> bb = b >>> id(bb) 1041552 >>> bb = True >>> id(bb) 1041552 布尔对象名称的大小写是至关重要的,因为true(和false)是未定义的: 清单6. 未定义的true和false >>> b = true Traceback (most recent call last): File "", line 1, in ? NameError: name 'true' is not defined 在这一点上,bool类型可能看起来不是很有用。不过顾名思义,布尔表达式是依赖于名称的,如下所示: 清单7. 布尔表达式 >>> b = 100 >> print b True 很多程序利用布尔表达式,Python提供一整套布尔比较和逻辑运算,详细信息请分别参见表1和表2。 表1. Python中的布尔比较运算符 运算符 描述 示例 大于 i > 100 >= 大于等于 i >= 100 == 相等 i == 100 != 不相等(另外使用 ) i != 100 补充一点,表1中列出的运算符优先级都一样,除非将表达式置于括号中,否则按从左到右的顺序应用。 表2. Python中的逻辑运算符 运算符 描述 示例 not 逻辑非 not b and 逻辑与 (i 100.1) 逻辑运算符的优先级低于单独的比较运算符,这一点意义重大,因为必须先计算比较运算符,然后才能计算逻辑运算符。逻辑运算符的实际优先级就是表2中罗列这些运算符的顺序。 在Python中,关于or和and逻辑运算符有意思的是,它们都是快捷运算符。简言之,如果给定表达式x or y,则仅当x为False时才会计算y。同样地,如果给定表达式x and y,则仅当x为True 时,才会计算y。此功能可以增强表达式求值的性能(尤其是针对长的或复杂的表达式),然而对于习惯于从其他语言学来的不同规则的程序员而言,则容易犯错。 数值类型 Python中其他四个简单的内置类型都是数值类型:int、long、float和complex。在程序中,数值类型很常见,不管使用的是什么语言。Python对算术运算提供完整支持,包括加法、减法、乘法和除法(参见表 3)。 表3. Python中的算术运算 运算符 描述 示例 * 乘 i * 100 / 除 i / 100 // 整除 i // 100 % 取余 f % 100 + 加 i + 100 - 减 i - 100 乘法和除法运算符(表3中列出的前四个)具有高于加法和减法的优先级。如前所述,您可以通过使用括号分组子表达式,将其分离出来以提高优先级。 Python与Java语言不同,Java语言通常定义允许的数值类型的范围,而Python在这一点上更像C,因为它的类型范围是依赖于平台的。您可以使用int和long两种类型来保存整数值,它们的不同点在于int是一种32位的整数值。因而,它被限制为只能保存从-2^32 到2^32 - 1之间的值(在多数平台上)。与此相反,长整数类型的精度不受限,仅计算机内存对它有影响。要通知Python应该按照长类型处理整数,只需将L附加到数字的末尾,如100L。在Python中,浮点值始终是按双精度处理的;因此Python的float类型对应于C类语言中的双精度。 与数值类型相关的其他两个重点是常量(如上例中的100,只是明确表达的数字)和位运算。程序员一般在十进制系统(以10为基数)中工作。但是,有时其他系统也相当有用,尤其是我们知道计算机是基于二进制的。Python可以提供对八进制(以8为基数)和十六进制(以16为基数)数字的支持。要通知Python应该按八进制数字常量处理数字,只需将零附加在前面。将一个零加上一个x附加在数字的前面是告诉Python按十六进制数值常量处理数字,如以下代码所示: 清单8. 通知Python按十六进制数值常量处理数字 >>> print 127 # Using decimal literal 127 >>> print 0177 # Using octal literal 127 >>> print 0x7F # Using hexadecimal literal 127 当您具有容易的方式来表达数值常量时,尤其是十六进制,就可以容易地构建对应于特定测试用例的标志,这是一种常见的编程技术。例如,一个32位的整数可以存储32个标志值。使用位测试,可以容易地测试标志变量上的特定标志。Python中位运算的完整列表如表4所示。 表4. Python中的位运算 运算符 描述 示例 ~ 按位求补 ~b > 向右位移 b >> 1 & 按位和 b & 0x01 ^ 按位异或 b ^ 0x01 | 按位或 b | 0x01 至此,您可能想知道不同数值类型在单个表达式中混合出现的时候怎么办。简单的答复是,Python会根据需要将表达式中的所有操作数转换为最复杂的操作数的类型。复杂度的顺序是:int、long、float和complex(非双关),下面是一个简单的示例: 清单9. Python将所有操作数转换为最复杂的操作数 >>> 1 / 3 0 >>> 1.0 / 3 0.33333333333333331 >>> 1.0 // 3 0.0 >>> 1 % 3 1 >>> 1.0 % 3 1.0 尽管Python会与您预期的一样转换操作数,但是语言并不基于运算符转换操作数,如1/3示例中所示,其计算结果为整数。如果要强制取得浮点结果,则必须确保操作数中至少有一个为浮点类型。 complex类型 最后一种类型complex可能是大多数程序员难以识别的,因为它不是其他编程语言中常见的内置数据类型。而对于工程师和科学家来说,复数却是个司空见惯的概念。从形式上讲,复数具有实部和虚部两个部分,都由Python中的float类型来表示。虚数是-1的平方根的倍数,用i或j表示——取决于您被培养为科学家还是工程师。在Python中,复数的虚部被表示为j: 清单10. 复数的虚部 >>> c = 3.0 + 1.2j >>> print c (3+1.2j) >>> print c.real, c.imag 3.0 1.2 本例是一个实部为3.0和虚部为1.2的复数。注意,通过使用复数对象的real和imag属性,即可访问复数的不同部分。 它们真是对象吗? 到此为止,我已经介绍了Python只处理对象类型,然而示例中好像并没有什么对象。最后还有一个问题,构造函数在哪里?对于简单的内置数据类型,Python替您做了大量的工作。不过,构造函数还在那里(其名称与相关数据类型的名称相同),如果您愿意,可以直接使用它们,如下所示: 清单11. Python构造函数 >>> b = bool(True) >>> i = int(100) >>> l = long(100) >>> f = float(100.1) >>> c = complex(3.0, 1.2) >>> print b, i, l, f, c True 100 100 100.1 (3+1.2j) 结束语 Python是一种无比简单又功能强大的语言,入门极其容易,尤其是对于已经具有C类语言的经验的程序员来说。本文简单介绍了Python编程语言和内置数据类型:bool、int、long、float和complex。如果您尚未理解,则请启动一个Python解释器,并尝试按照我上面讨论的方法操作。您将会很高兴,我做到的您也可以做到。 参考资料
Robert J. Brunner是National Center for Supercomputing Applications的一名研究科学家和伊利诺斯州大学香槟分校的天文学助理副教授。他曾经就一系列主题发表多部著作,及大量文章和教程。 |