您的位置:首页 > 编程语言 > Python开发

探索 Python,第 1 部分: Python 的内置数值类型

2006-04-16 21:21 836 查看
级别: 初级

Robert J. Brunner, 研究科学家

2005 年 6 月 06 日

Python 编程语言具有很高的灵活性,它支持多种编程方法,包括过程化的、面向对象的和函数式的。但最重要的是,在 Python 中编写程序是件令人愉悦的事。该语言对开发进程有支持作用,决不会妨碍它。本文是关于 Python 编程系列文章的第一篇,主要介绍 Python 及其内置数值类型。

Python 是一种敏捷的、动态类型化的、极富表现力的开源编程语言,可以被自由地安装到多种平台上(参阅 参考资料)。Python 代码是被解释的。如果您对编辑、构建和执行循环较为熟悉,则 Python 代码对您来说更简单。但是,请不要搞错:Python 器可以是简单的脚本,也可以是大型的复杂程序。事实上,Python 解释器的最大特点是鼓励探索和简化学习过程。如果您想证明这一点,请使用 Python 编写著名的 Hello World! 程序:

启动 Python 解释器。在 UNIX 系统(包括 Mac OS X)中,启动解释器通常包括在命令提示行键入
python
;在 Microsoft® Windows® 系统中,启动 Python 命令 shell。
在 Python 提示行中,在三个大于号 (
>>>
) 标志后输入 print '
Hello World!
',然后按 Enter
完成:没有第三步了。清单 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 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)
<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) and (b == True)
or
逻辑或
(i < 100) or (f > 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 位的整数值。因而,它被限制为只能保存从 -232 到 232 - 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 的平方根的倍数,用 ij 表示 —— 取决于您被培养为科学家还是工程师。在 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 解释器,并尝试按照我上面讨论的方法操作。您将会很高兴,我做到的您也可以做到。








回页首
参考资料

您可以参阅本文在 developerWorks 全球站点上的 英文原文

下载 Python

当您具有了正常运行的 Python 解释器时,Python 教程 是您学习该语言的理想去处。

IBM developerWorks 发表了很多关于 Python 的文章,David Mertz 撰写的高级的 可爱的 Python 专栏 就是其中之一。

如果您更习惯于使用 IDE,则可阅读 Ron Smith 撰写的 用 Eclipse 和 Ant 进行 Python 开发,这篇文章介绍了使用 Eclipse 编写 Python 代码的方式。

The Python Reference Manual 提供 Python 对象属性 的讨论。

The Python Reference Manual 还可提供 整数常量浮点常量 的合法细节。

复数并非仅供科学家和工程师使用。它们还可用于图形工作,如简化 GUI 上对象的旋转

通过参与 developerWorks blogs 加入 developerWorks 社区。








回页首
关于作者



Robert J. Brunner 是 National Center for Supercomputing Applications 的一名研究科学家和伊利诺斯州大学香槟分校的天文学助理副教授。他曾经就一系列主题发表多部著作,及大量文章和教程。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: