本节书摘来自华章出版社《Python树莓派编程》一书中的第3章,第3.3节,作者:[美]沃尔弗拉姆·多纳特(Wolfram Donat)著韩德强 等译,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
3.3 Python入门
让我们开始学习Python吧。在树莓派上运行Python有3种不同的方法:使用内置的IDLE解释器,在终端内运行,或者用作脚本文件。我们先介绍IDLE。
3.3.1 通过IDLE运行Python
IDLE编辑器类似于一个“沙盒”,你无需编写全部脚本内容便可同Python进行交互,并观测它所做的事情。IDLE代表“Integrated DeveLopment Environment”,集成开发环境,它也代表了对Eric
Idle的一种尊敬,Eric Idle是英国戏剧团体Monty Python的联合创始人之一(详情见“给我一个灌木丛!”部分)。
IDLE是调试代码最为友好的一种方式,首先,让我们看看它的使用方法。双击桌面的图标(见图3-1),之后你便可以看到如图3-2所示的欢迎界面。
为了迎合大多数的编程传统,让我们编写一个很多种语言都编写过的程序,在光标处输入:
按下Enter键,你会立刻看到屏幕输出:
这便是Python的print语句,默认输出到屏幕上。现在输入:
按下Enter键。光标会跳到下一行,但什么都没发生。实际上,Python解释器已经将x与4进行关联了。如果现在你输入:
会得到:
同样,如果你输入:
也会得到同样的结果:
这表明了Python的另一个特性:动态类型化(dynamic typing)。在类C等语言中,使用变量前必须先定义它的类型,比如:
或者
关于字符串的内容请见本章“字符串”一节。
当你输入x = 5时,Python“知道”x是一个int(整型)变量。
虽然Python采用动态类型系统,它同时也是强类型的。这意味着当你试图将一个int类型的变量与一个string类型的变量相加时,Python会进行错误提示。你也可以使用类来定义自己的类型。Python完全支持object-oriented programming(OOP,面向对象编程),我之后会对此进行详解,但此处你只需知道你可以创建一个包含有整型、字符串型和其他类型的对象,而且这个对象属于它自己的类型即可。Python有一些内置的数据类型:数值、字符串、列表、字典、无组、文件,以及其他类型(如布尔类型)。之后我们会对每个类型逐一进行介绍。
现在回到之前的话题,让我们尝试在IDLE中对变量进行一些操作。输入:
会输出9,如果输入:
则会提示error。此时,如果输入:
会得到:
因为对Python而言,对字符串进行加操作就相当于串联它们。如果你想制作一个列表,则将列表中的每一项置于方括号内:
同样,对于一个字典集合(一组有着键码和键值的文件类型),将内容置于花括号内:
键码和键值都是Python字典数据类型的一部分,它们是链接在一起的数据对。例如,在之前代码示例的字典里,'food'和'spam'分别为键码和键值。同样,'taste'和'yum'也是这样的一组数据。当使用字典时,你输入其键码,便会得到相关联的键值信息。
给我一个灌木丛!
Python这个名字并不是来源于一条蛇。它的创始人van
Rossum,是根据BBC的一个喜剧团体Monty Python的名字来命名这门语言的,因为他本人十分喜欢该团体。因此,这门语言中充斥着很多Monty Python的文献内容。传统上“foo”和“bar”在其他编程语言中用来解释代码,而在Python的例子中则变成了“spam”和“eggs”。如果你是Monty Python的一名粉丝,当你看到“Brian”、“ni”和“shrubbery”等这些词语时,便会觉得一切都变得意义非凡了。即便是编译器IDLE,也是根据M.P.的成员Eric Idle命名的。如果你不是很了解他们的作品,我建议你放下本书,去看看他们的事迹。我真诚推荐The Dead Parrot Sketch和The Ministry of Silly Walks,尽管学习这门语言不必了解他们的作品,但这会让你更加享受Python。
3.3.2 通过终端运行Python
让我们快速浏览另一种使用Python的方法,即通过终端使用Python。打开树莓派桌面的终端,在光标处输入Python。之后你会看到和打开IDLE同样的欢迎信息,以及同样的>>>符号。此时,你可以尝试输入在3.3.1节中我们讨论过的相同的命令,而且你会得到相同的结果。
3.3.3 通过脚本运行Python
无论是通过IDLE还是终端,你都无法在真正意义上编写一个“脚本文件”。因为一旦你将窗口关闭,之前定义的变量便荡然无存,而且没有办法保存你之前的工作。而编写Python的最后一个方法(使用文本编辑器编写)解决了这个问题。你可以编写一个完整的程序,保存为.py文件,并且通过终端运行。
现在,让我们用树莓派自带的文本编辑器Leafpad编写一段非常简短的脚本程序。从Accessories菜单中打开Leafpad(见图3-3)。
在打开的窗口中,输入:
将该文件命名为test.py保存至桌面。现在开启一个终端程序并将目录转至桌面,输入:
之后你便可以运行刚才的脚本了,输入:
终端上便会显示数字6了。恭喜!你刚刚已经完成了包括编写、保存、执行一个Python脚本程序最基本的操作!
在编写本书中的脚本程序时,你可以使用任何一种文本编辑器。如果你习惯使用Leafpad,就尽情使用吧。我习惯用nano或者emacs这些基于终端的编辑器,因为我经常远程登录树莓派,但Leafpad不能运行在远程登录会话中。为此,我将告诉你如下编写文件的方式:
不过,按自己喜好使用编辑器就好。
接下来,让我们简单看看每一种数据类型以及它们能用来做什么。
3.3.4 探究Python的数据类型
像我们之前提到过的那样,Python提供了很多内置的数据类型。在接下来的环节中,你会接触到数值、字符串、列表、字典、元组和文件这几个数据类型。
1. 数值
数值的含义不言而喻,实际上,如果之前有过编程经验你便会了解Python的数值类型:整型、短整型、长整型、浮点类型,以及其他。Python中有一些表达式运算符可以允许你对这些数字进行计算,包括+、–、/、*、和%;一些比较运算符如>、>=、!=、or和and。还有很多其他的运算符。
所有这些运算符都是内置的,但你可以通过Python另一个强大的特性(导入模块),导入其他的运算符。模块是你可以导入脚本并将其添加至Python本地功能的额外的库。在这一点上,Python和Java很像:如果你想做一些其他操作,导入一个已存在的库会使事情变得十分轻松。例如,如果你想分析文本,例如分析网页页面,你可以查看一个叫Beautiful Soup的模块。如果你需要远程登录一台计算机(如果愿意,用一些其他的项目也可以),导入telnetlib这个模块,这样你需要的一切就齐备了。至于数值的操作,math模块中包含有各种各样的数学函数,可以用来增加Python的数学功能。你可以自己试试,打开一个IDLE,输入:
你会得到16。因为这是一个绝对值功能的函数(我会在本章函数内容部分进行讨论),而且这个函数已经包含在Python默认库内。但是,如果输入:
便会出错,因为ceiling功能并不包含在默认库内。它必须被导入。输入:
之后终端会得到17.0的结果—x的ceiling值,或者说是大于x的最小整数。然而你也许不会用到ceiling功能,但导入math模块会给你提供各种额外的功能,如对数和三角函数功能及角度转换的功能,而添加这些功能只需要一行代码。
2. 字符串
在Python中,字符串定义为一组有序的用于表示基于文字信息的字符集合。Python并没有像C语言或其他语言中的char类型变量,一个单字符就是简单的单字符字符串。字符串可包含任何可视为文本的信息:字母、数字、标点符号、程序名等。当然,这意味着:
和
并不相同。你可以向第一个示例中的x加3,但如果你对第二个示例做同样的事情,Python并不会提示错误—此处x指向值为4的字符串,而不是一个整数,因为4是用引号括起来的。Python并不区分单引号或双引号,你可用任意一种括起一些字符,而被引号括起的内容则被视为字符串。这会起到很好效果:你可以在字符串内包含一个引号字符,而不需要像C语言那样通过反斜杠对引号进行转义。例如:
意味着:
并不需要转义字符。
在使用Python的过程中,你可能会经常使用一些基本的字符串操作,如len(计算字符串的长度)、连接、迭代、索引和切片(相当于Python中的子字符串操作)。为了更加详细地说明,请在IDLE中输入如下的代码,对比你得到的结果和下面给出的结果:
‘shrubbery’的长度为9个字符。
‘spam’、‘and’、‘eggs’单个字符串连接了。
输出‘title’中的每一个字符。
“spam”中第一个([0])和第三个([2])字符分别是:'s'和'a'。
第二个到第四个字符是'pa'。(当在字符串中确定范围时,一般不包含第一个参数,而包含第二个参数。)
如果有一个整数(例如4)以字符串类型输入,你可以将其从string类型转换成int类型,如果你需要将其平方,只要简单输入:
你可以转换至ASCII码或者从ASCII码转换成字符串类型,使用类似于%d和%s这类转义字符进行格式化即可,或者将大写字符全部转换为小写字符,有很多其他的类似操作全部包含在Python内置的string库中。
3. 列表
列表和字典可以说是Python中最强大的内置数据结构。实际上它们是其他数据类型的集合,而且使用起来十分灵活。它们可以在位置上进行改变,根据需求扩展或者收缩,而且可以包含其他类型的对象或被它们所包含。
如果你有使用过其他编程语言的经历,可能会认为Python中的列表和C语言中的指针数组有些相似。实际上,在Python编译器内,列表就相当于C语言中的数组。由于它们包含的指针对象可以指向几乎任意一种数据类型(包括其他列表),因此它们可以包含任意其他数据类型的对象。列表也是可以建立索引的—同C语言中数组建立索引的速度一样快。它们可以像C++和C#中的列表一样扩展和收缩,也可以被分割成不同列表或者独立成一个元素,还可以进行串联—你对字符串进行的诸多操作同样适用于列表。
如果要创建一个列表,需要用方括号([])进行定义:
或者
创建好之后,你便可以对它们进行操作了,比如连接等:
(你可能会意识到在:列表同数组一样,索引是从0开始的。)通过索引和切片操作,你可以用删除或添加来改变队列的内容:
在列表中,你也可以调用一些相关的函数进行操作,如:append、sort、reverse和pop。如果想要获得最新列表的函数,输入:
这样你便可以知道最新函数的细节信息。
Python的帮助功能十分强大。如果你不知道该做什么或者什么做法可行时,在终端内输入help(困惑的内容),之后便可得到极大的帮助(更多内容可以参考“Python help”部分)。
Python help
如果你在使用Python时遇到了困难,提供的官方在线文档会十分有帮助。将浏览器转到http://docs.python.org/2/library/stdtypes.html,你就可以看到可用的所有标准数据类型的信息以及使用方法了。类似地,在http://docs.python.org/2/library/functions.html提供了经常使用的一些函数的所有信息。Python中内置的help功能也十分全面。如果想尝试help功能,在IDLE中输入:
之后输入:
接着,你就能看到你想知道的任何关于字符串的内容了。
4. 字典
类似于列表,Python中的字典也可以将其他数据对象灵活地组合在一起。但与列表不同的是,字典数据类型是不可排序的;你可以通过下标访问每组数据,但在字典中数据是通过键码进行访问的。换言之,字典包含键码–键值(key-value)数据对。每次访问键码都会返回键值的内容。例如,在下面的字典中,'spam'值可通过它的键码'food'进行访问:
同列表一样,字典也可以进行嵌套:
这意味着键码'ood'同{'ham' : 1, 'eggs' : 2}的内容相关联,而其本身就是一个字典类型数据。
字典类有明确的调用方法:
这条指令会列出在dict中的所有键码。
此处返回'True',意味着在dict中确实包含键值为'food'的数据,如果不包含的话则返回'False'。
字典类型数据的位置也可改变。
这使得'food'的键值从'spam'变成'eggs'。(在此你会发现:'eggs'不仅是一个普通项,也是一个单数据列表。)
如你所见,键码不一定必须是字符串类型。你可以使用任何不可变的对象作为键码;如果你使用整型变量作为键码,字典就会和列表的功能一样了—也就是通过序号(整型值)进行查找。
5. 元组和文件
在此要介绍的最后两个主要的数据类型是元组和文件。元组是其他对象的集合,而且数据不能更改,文件则是指在计算机上文件对象的接口。
元组是有序的对象的集合。它们很像列表,但不同于列表的是,元组的数据位置是不允许更改的,而且是通过圆括号描述的,不是方括号,如:
这里,t包含两个整型变量:一个字符串变量和一个列表。你可以对元组进行嵌套操作,索引编号操作,切片操作,以及任何你可以对列表进行的操作都适用于元组。
所以,既然它和列表如此相似,为何还有存在的必要呢?最为大众所接受的答案是:因为它所包含的内容是不可变的—它们不可更改。通过将一组对象定义为元组而不是列表,你可以确保在程序中任何地方使用相同的一组数据。这和C语言中定义的const变量有些类似—如果你想在某个位置对其进行修改,编译器会进行错误提示。
我在第2章曾提到过关于文件的内容,所以这个名词对你应该并不陌生。在Python中,有一个内置的open函数,可以用来创建一个文件对象,并与计算机内的一个文件建立链接。文件对象与其他类型有一些不同,它们只能对那些外部的文件进行一系列的操作。这些操作包括读(read)、写(write)、打开(open)、关闭(close),以及各种解析文本文件的函数。为了进行更详细的说明,在下面的代码中我将进行打开test.txt文件(如果文件不存在则创建新的文件)的操作,并对打开的文件进行写操作,写入一行文字(通过换行转义字符实现换行操作),最后关闭这个文件:
无论你在哪个目录下,执行这些指令后的结果都是一样的。
需要注意的是,如果test.txt已经存在,调用myfile.write()函数会将已存在的内容覆盖。如果你希望追加内容而不是覆盖,在打开文件时应使用'a'而不是'w'。
一旦打开了一个文件,你可以读取内容并写入内容,需要注意的是:你只能从文件读取字符串类型的内容。这意味着在你对文件内的对象进行任何操作之前,你不得不将其还原为它们“真正”的数据类型;如果myfile.readline()返回的值是'456',你必须通过int()将456转换为整型变量,之后才能进行计算。
文件操作十分实用,因为你可以对一个文件进行创建或者写操作,但它们有些超出本章介绍的范围。我将在项目中使用它们时再进行介绍。
如你所见,Python内置的数据类型可以完成一个真正的“编程语言”完成的事情—有时会更加方便更加有效。通过比较这些数据类型,你可以利用Python做出一些十分强大的东西,就如你在接下来的讲解中会看到的一样。