Python 是一种敏捷的、动态类型化的、极富表现力的开源编程语言,可以被自由地安装到多种平台上(参阅 参考资料)。Python
代码是被解释的。如果您对编辑、构建和执行循环较为熟悉,则 Python 代码对您来说更简单。但是,请不要搞错:Python 器可以是简单的脚本,也可以是大型的复杂程序。事实上,Python 解释器的最大特点是鼓励探索和简化学习过程。如果您想证明这一点,请使用 Python 编写著名的 Hello
World! 程序:
- 启动 Python 解释器。在 UNIX 系统(包括 Mac OS X)中,启动解释器通常包括在命令提示行键入
python
;在
Microsoft® Windows® 系统中,启动 Python 命令 shell。 - 在 Python 提示行中,在三个大于号 (
>>>
)
标志后输入 print 'Hello
',然后按 Enter。
World! - 完成:没有第三步了。清单 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 World!
您可以看到,我使用的是运行于 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
来创建和初始化整型变量。在 Java 和 C# 中,此方法也是可能的,而且使用它们的自动装箱功能,在需要时这两种语言还可以把这种简单的内置类型转换为
i = 100Integer
对象。
另一方面,Python 不包含像 int 这样的简单类型 —— 只有对象类型。如果 Python 中需要整数值,将整数赋值给相应变量(如 i
)即可。在后台,Python 将创建一个整数对象,并将对新对象的引用赋值给变量。问题的关键是:Python 是一种动态类型化语言,所以无需声明变量类型。事实上在单个程序中,变量的类型是可以改变(多次)的。
= 100
一种直观演示动态类型化工作方式的简单方法是,设想单个名为 PyObject
的基类,让
Python 中的所有其他对象类型都继承它。在这一模型中,您创建的所有变量都将引用在总的类层次结构中创建的对象。如果您还让 PyObject
类记录曾创建并分配给变量的子类的实际类型或名称,则
Python 程序可正确确定程序执行过程中需要采取的步骤。
上一段描述 Python 的面向对象的模型图像是对 Python 的实际工作方式很好的模拟。除此之外,Python 还可以使用类型函数来简化对变量类型的确定。(本例还介绍如何使用带有 # 字符的内联注释。)
清单 2. 演示 Python 简单类型
>>> i = 100 # Create an int object whose value is 100
>>> type(i)
<type 'int'>
>>> f = 100.0
>>> type(f)
<type 'float'>
可以将 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)
<type 'bool'>
>>> 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 "<stdin>", line 1, in ?
NameError: name 'true' is not defined
在这一点上,bool
类型可能看起来不是很有用。不过顾名思义,布尔表达式是依赖于名称的,如下所示:
清单 7. 布尔表达式
>>> b = 100 < 101
>>> print b
True
很多程序利用布尔表达式,Python 提供一整套布尔比较和逻辑运算,详细信息请分别参见表 1 和表 2。
表 1. Python 中的布尔比较运算符
< | 小于 | i < 100 |
<= | 小于等于 | i <= 100 |
> | 大于 | i > 100 |
>= | 大于等于 | i >= 100 |
== | 相等 | i == 100 |
!= | 不相等(另外使用 <>) | i != 100 |
补充一点,表 1 中列出的运算符优先级都一样,除非将表达式置于括号中,否则按从左到右的顺序应用。
表 2. Python 中的逻辑运算符
not | 逻辑非 | not b |
and | 逻辑与 | (i <= 100) |
or | 逻辑或 | (i < 100) |
逻辑运算符的优先级低于单独的比较运算符,这一点意义重大,因为必须先计算比较运算符,然后才能计算逻辑运算符。逻辑运算符的实际优先级就是表 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 到 2 -
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 >> 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 解释器,并尝试按照我上面讨论的方法操作。您将会很高兴,我做到的您也可以做到。
Python 技术专题
Python 是由 Guido van Rossum 开发的,可免费获得的。是一种非常高级的解释型语言。其语法简单易懂,而且面向对象的语义功能强大又灵活,Python 可以广泛使用并具有高度的可移植性。本专题内容包括可爱的 Python 系列、Python 探索系列、Python 扩展、使用 Python 进行各种应用开发等等。
可爱的 Python 系列
- 可爱的
Python:将 XML 和 Python 结合起来 介绍 Python 的 XML 工具 - 可爱的
Python:DOM 的动态性近观 Python 的 xml.dom 模块 - 可爱的
Python:我的第一个基于 Web 的过滤 proxy 使用 Txt2Html 转换文本到 HTML - 可爱的
Python:使用状态机 - 可爱的
Python:Python 中的文本处理 入门者提示 - 可爱的
Python:Curses 编程 入门提示 - 可爱的
Python :Python 的实现内幕 Interviews with the creators of Vyper and Stackless Python - 可爱的
Python:动态重新装入 - 可爱的
Python:JPython 和 Python for .NET 内幕 采访创始人 - 可爱的
Python:Python 中的函数编程 -- 让您喜爱的脚本语言发挥更大功效 - 可爱的
Python:获得版本 2.0 - 可爱的
Python:Python 中的 TK编程 -- 给使用 Python GUI 库的初学者的提示 - 可爱的
Python:在 Python 下开发全文索引 - 可爱的
Python:Python IDE 测评 - 可爱的
Python:重温 Python 的 XML 工具 - 可爱的
Python:Python 中的函数编程,第 2 部分 - 可爱的
Python:在 Python 中进行函数编程,第 3 部分 - 可爱的
Python:用于 PalmOS 的 Python - 可爱的
Python:pydoc 和 distutils 模块 - 可爱的
Python:迭代器和简单生成器 - 可爱的
Python:[anygui] 项目预览 - 可爱的
Python:更新您的 Python 读物列表,第 2 部分 - 可爱的
Python:使用 SimpleParse 模块进行解析 - 可爱的
Python:更新您的 Python 读物列表,第 3 部分 - 可爱的
Python:用 Python 生成器实现“轻便线程” - 可爱的
Python:基于生成器的状态机 - 可爱的
Python:使用 Spark 模块解析 - 可爱的
Python:用 Psyco 让 Python 运行得像 C 一样快 - 可爱的
Python:创建声明性迷你语言 -- 编程为断言而不是指令 - 可爱的
Python:使用 itertools 模块中的组合函数 -- Python 中的函数编程变“懒惰”了 - 可爱的
Python: Numerical Python -- 使用 Numeric 软件包和 Numarray 软件包 - 可爱的
Python:点评 Python IDE -- Python 开发变得更容易 - 可爱的
Python:Python 中的测试框架 -- 确保软件如您所愿地工作 - 可爱的
Python:Python Enterprise Application Kit -- 在 Python 中对协议使用 PEAK - 可爱的
Python:了解 DParser for Python - 可爱的
Python:用 hashcash 打击垃圾邮件 - 可爱的
Python:Pyrex 可扩展并加速 Python 应用 - 可爱的
Python:深入 PEAK 的新特性 - 可爱的
Python:使用 setuptools 孵化 Python egg - 可爱的
Python:Decorator 简化元编程 - 可爱的
Python:Python 之优雅与瑕疵,第 1 部分 - 可爱的
Python: Python 之优雅与瑕疵,第 2 部分 - 可爱的
Python:自然语言工具包入门 - 可爱的
Python:SimPy 简化了复杂模型
使用 Python 构建网格应用程序
- 使用
Python 构建网格应用程序,第 1 部分:介绍 - 用
Python 构建网格应用程序,第 2 部分:通信 - 用
Python 构建网格应用程序,第 3 部分:安全性 - 用
Python 构建网格应用程序,第 4 部分:元数据 - 使用
Python 构建网格应用程序,第 5 部分:跟踪和管理
探索 Python 系列
- 探索
Python,第 1 部分:Python 的内置数值类型 - 探索
Python,第 2 部分:探索 Python 类型的层次结构 - 探索
Python,第 3 部分:探索 Python 类型的层次结构 - 探索
Python,第 4 部分:探索 Python 类型的层次结构 - 探索
Python,第 6 部分:用 Python 编程 - 探索
Python,第 5 部分:用 Python 编程 - 探索
Python,第 7 部分:探索 Python 类型层次结构 - 探索
Python,第 9 部分:化零为整 - 探索
Python,第 8 部分
Python Web 服务开发者系列
- Python
Web 服务开发者:第 1 部分 - Python
Web 服务开发者,第 2 部分:Web 服务软件资源库,第 1 部分 - Python
Web 服务开发者 第 5 部分:Python SOAP 库 - Python
Web 服务开发者 第 6 部分:Python SOAP 库,第 2 部分 - Python
Web 服务开发者 第 7 部分:第十届国际 Python 大会 - Python
Web 服务开发者 第 8 部分:Python SOAP 库,第 3 部分 - Python
Web 服务开发者:针对 Python 的 XML-RPC - Python
Web 服务开发者:消息传递技术比较 - Python
Web 服务开发人员: 用于 Python 的 RSS - Python
Web 服务开发者:通过 SMTP 处理 SOAP - Python
Web 服务开发者:三股力量:Python、Web 服务和 XSLT - Python
Web 服务开发者:现实世界,第 2 部分 - Python
Web 服务开发者:Python SOAP 库,第 5 部分 - Python
Web 服务开发者: Python SOAP 库,第 4 部分 - 使用
python 开发 Web Service - Python
Web 服务开发人员:现实世界,第一部分
Python 与数据源
- 使用
SQLObject 连接数据库与 Python - 使用
Python 连接 Apache Derby 数据库 - 基于
Python 与 DB2 Express-C 的应用开发 - 使用
Python 访问 DB2 for Linux
使用 Python 进行 socket、web、桌面开发
- Linux
socket 编程,第一部分 - Linux
Socket 编程,第二部分 - 使用
Python 进行 socket 编程 - Python
Web 框架,第 1 部分:使用 Django 和 Python 开发 Web 站点 - Python
Web 框架,第 2 部分:使用 TurboGears 和 Python 开发 Web 站点 - 基于
Django 框架的敏捷 Web 开发 - 针对
OLPC 膝上型电脑的应用程序开发(教程) - 针对
OLPC 膝上型电脑的桌面开发
Python 设计模式系列
- 用模式改善软件设计
- 创建型
Simple Factory 模式 - Python设计模式系列之三
-- 创建型Factory Method模式 - Python设计模式系列之四
-- 创建型Abstract Factory模式
Python 扩展
- 细述
wxWindows -- 可移植 C++ 和 Python 工具箱简介 - 供初学者使用的
wxHTML - 集成
Pyrite 的 Palm-Linux - 用
C 扩展 Python 和 Zope - 供初学者使用的
wxHTML - Python
自省指南 -- 如何监视您的 Python 对象 - Qt
和 PyQt -- 用于 Python 的高级 GUI 库 - 用C语言扩展Python的功能
- 在
Python 中封装 GObject -- 您不必是 C 专家就可以为 Python 封装模块 - 使用
Python 编织神经网络 - Python
与 Gnumeric 共舞 - 基于
Python Matplotlib 模块的高质量图形输出 - 适用于
CGI 程序员的 CherryPy - Python
中的元类编程,第 2 部分 -- 理解继承的奥秘和实例创建 - Python
中的元类编程,第 3 部分:不用元类进行元编程