当前位置: 首页 > 新闻 > 信息荟萃
编号:6077
Python从入门到精通清华大学出版社.pdf
http://www.100md.com 2020年11月27日
第1页
第6页
第18页
第26页
第33页
第180页

    参见附件(7186KB,569页)。

     《Python从入门到精通》从初学者角度出发,通过通俗易懂的语言、丰富多彩的实例,详细介绍了使用Python进行程序开发应该掌握的各方面技术

    编辑推荐

    软件开发视频大讲堂”丛书是清华社计算机专业基础类零售图书畅销的品牌之一。

    丛书累计销售180多万册,深受广大开发者喜爱。

    4本荣获“全行业优畅销书”奖,1本荣获清华社“专业畅销书”一等奖。

    绝大多数品种在“全国计算机零售图书排行榜”同品种排行中名列前茅。

    实用、易懂、资源丰富,被 数百所高校选为专业课教材。

    内容简介

    全书共分22章,包括初识Python、Python语言基础、运算符与表达式、流程控制语句、列表与元组、字典与集合、字符串、Python中使用正则表达式、函数、面向对象程序设计、模块、异常处理及程序调试、文件及目录操作、操作数据库、GUI界面编程、Pygame游戏编程、网络爬虫开发、使用进程和线程、网络编程、Web编程、Flask框架、e起去旅行网站等。所有知识都结合具体实例进行介绍,涉及的程序代码都给出了详细的注释,读者可轻松领会Python程序开发的精髓,快速提升开发技能。除此之外,本书还附配了235集高清教学微视频及PPT电子教案。

    本书内容

    本书提供了从入门到编程高手所必备的各类知识,共分4篇,大体结构如下图所示。

    第1篇:基础知识。本篇包括Python简介、搭建Python开发环境、Python开发工具、Python语法特点、Python中的变量、基本数据类型、基本输入和输出、运算符与表达式、流程控制语句、列表与元组、字典与集合以及字符串等语言基础方面的知识。介绍时结合大量的图示、举例、视频,使读者能快速掌握Python语言,并为以后编程奠定坚实的基础。

    第2篇:进阶提高。本篇包括Python中使用正则表达式、函数、面向对象程序设计、模块、异常处理及程序调试、文件及目录操作、操作数据库等内容。学习完本篇,读者可以掌握更深一层的Python开发技术。

    第3篇:高级应用。本篇包括GUI界面编程、Pygame游戏编程、网络爬虫开发、使用进程和线程、网络编程、Web编程、Flask框架等内容。学习完本篇,读者将能够开发GUI界面程序、简单的游戏、网络爬虫、网络及Web程序等。

    第4篇:项目实战。本篇通过一个完整的Web项目——e起去旅行网站,运用软件工程的设计思想,引导读者学习如何进行软件项目的实践开发。书中按照“系统功能设计→数据库设计→前台模块设计→后台模块设计”的流程进行介绍,带领读者亲身体验使用Flask框架开发Web项目的全过程。

    本书特点

    由浅入深,循序渐进。本书以初、中级程序员为对象,先从Python语言基础学起,然后学习Python的进阶与提高技术,接下来再学习Pyhton的高级应用,最后学习开发一个完整的Web项目。讲解过程中步骤详尽,版式新颖,在操作的内容图片上以uvw……编号+内容的方式进行标注,让读者在阅读中一目了然,从而快速把握书中内容。

    语音视频,讲解详尽。对于初学者来说,视频讲解是最好的导师,它能够引导初学者快速入门,使初学者感受到编程的快乐和成就感,进一步增强学习的信心。鉴于此,本书为大部分章节都配备了视频讲解,使用手机扫描正文小节标题一侧的二维码,即可在线学习程序开发的全过程。

    实例典型,轻松易学。通过实例学习是最好的学习方式,本书通过“一个知识点、一个例子、一个结果、一段评析、一个综合应用”的模式,透彻详尽地讲述了实际开发中所需的各类知识。另外,为了便于读者阅读程序代码,快速学习编程技能,书中几乎每行代码都提供了注释。

    精彩栏目,贴心提醒。本书根据需要在各章使用了很多“注意”“说明”“常见错误”等小栏目,读者可以在学习过程中轻松理解相关知识点及概念,快速掌握相应技术的应用技巧。

    Python从入门到精通清华大学出版社截图

    书名:跟老齐学Python:从入门到精通

    作者:齐伟

    出版社:电子工业出版社

    ISBN:978-7-121-28034-4

    定价:69.00

    版权所有·侵权必究前言

    这是一本学习材料,是为编程“零基础”的朋友学习Python提供的类

    似教材的学习材料,所以,内容会有庞杂琐碎之感,但这对于“零基

    础”的读者来讲是不可缺少的。所以,不要把这本书当作“开发手册”来

    用。

    本书虽然是以“零基础”起步,但是并不打算仅仅涉及一些浅显的入

    门知识,当然基础知识是必不可少的,还想为“零基础”的朋友多提供一

    些知识,一些所谓高级的内容,既满足了好奇心,也可以顺势深入研

    究。当然,真正的深入还需要读者自己努力。

    “敬畏上帝是智慧的开端”。在本书的编写过程中,一直惶恐于能否

    所言无误,但水平有限,错误难免,敬请读者指出,并特别建议,对有

    异议的地方,请使用Google网站搜索更多的资料进行比较阅读,也可以

    跟我联系,共同探讨。为了便于进行技术交流,我创建了一个QQ群

    (群号:26913719),专供本书读者研讨技术问题。

    完成本书是一个比较漫长的过程,在这个过程中,得到了很多朋友

    的帮助,在这里对他们表示感谢,并将他们的名号列在下面:

    李航、令狐虫、github641、dongm2ez、wdyggh、codexc、winecat、solarhell、ArtinHuang、吴优。

    在本书编辑过程中,电子工业出版社的编辑高洪霞、黄爱萍为本书

    的面世做出了极大的努力,对她们的工作表示诚挚感谢。

    最后,要感谢我的妻子,在本书的写作过程中,她给了我很多鼓

    励,还协助我检查文本内容。希望这本书能够为有意学习Python的读者提供帮助。

    齐伟

    2016年1月第1季 基础

    从这里开始,请读者——你已经确信自己是要学习Python的准程序

    员了——跟我一起,领略一番Python的基础知识,这是学好Python的起

    步,同时,其内容也和其他的高级编程语言有相通之处。所以,学习

    Python是一种“性价比”非常高的事情。

    在本季中,要向读者介绍Python的基本对象类型、语法规则和函数

    的相关知识。学习完这些内容,就能够用Python做很多事情了,且在其

    中还会不断强化一种掌握Python的方法。第0章 预备

    从现在开始,本书将带领你——零基础的学习者——进入到Python

    世界。进入这个世界,你不仅能够体会到Python的魅力,感受到编程的

    快乐,还顺便可以成为一个程序员,我相信你一定能成为一个伟大的程

    序员,当然这并不是本书的目的,更不是本书的功劳。当你成为一个技

    术大牛的时候,最应该感谢的是你的父母,如果你顺便也感谢一下本

    书,比如多购买一些本书分发给你的弟兄们,那是我的福份,感激不

    尽。

    预备,Let’s go!0.1 关于Python的故事

    学习一种编程语言是一件很有意思的事情,从现在开始,我就和你

    一起来学习一种叫作Python的编程语言。

    在编程界,存在着很多某种语言的忠实跟随者,因为忠实,就会如

    同卫道士一样有了维护那种语言荣誉的义务,所以总见到有人争论哪种

    语言好、哪种语言不好。当然,好与坏的标准是不一样的,有些人以学

    了之后能不能挣大钱为标准,有些人以是否容易学为标准,或许还有人

    以能不能将来和妹子一同工作为标准(也或许没有),甚至有些人就没

    有什么标准,只是凭感觉或者道听途说而人云亦云罢了。

    读者在本书中将看到一个颇为迷恋于Python的人,因为全书看不到

    一句有关Python的坏话(如果有,则肯定是笔误,是应该删除的部

    分)。

    不管是语言还是其他什么,挑缺点是比较容易的事情,但找优点都

    是困难的,所以,《圣经》中那句话——为什么你看见弟兄的眼中有

    刺,却不想自己眼中有梁木呢?——是值得我们牢记的。

    在本书开始就废话连篇,显见本书不会有什么“干货”,倒是“水

    货”颇多,并不是因为“水是生命的源泉”,而是因为作者水平有限,如

    果不掺“水”,唯恐说不清道不明,还敬请读者谅解。嫌“水”多的,就此

    可以合上本书去看网上的各种电影吧。也不用在网上喷我,因为那样只

    能增加更多的“口水”(还是水)。

    下面说点儿正经的。

    0.1.1 Python的昨天、今天和明天

    这个题目有点大了,似乎回顾过去、考察现在、张望未来都是那些

    掌握方向的大人物做的。那就让我们每个人都成为大人物吧。因为如果不回顾一下历史,似乎无法满足好奇心;如果不考察一下现在,也不放

    心(担心学了之后没有什么用途);如果不张望一下未来,怎么能吸引

    (也算是一种忽悠吧)你呢?

    1.Python的历史

    历史向来是成功者的传记,现在流传的关于Python的历史也是如

    此。

    Python的创始人为吉多·范罗苏姆(Guido van Rossum),关于他开

    发Python的过程,很多资料里面都要记录下面的故事:

    1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时

    间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承。之所

    以选中Python作为程序的名字,是因为他是一个蒙提·派森的飞行马戏团

    的爱好者。ABC是由吉多参加设计的一种教学语言,在吉多本人看来,ABC这种语言非常优美和强大,是专门为非专业程序员设计的。但是

    ABC语言并没有成功,究其原因,吉多认为是非开放造成的。吉多决心

    在Python中避免这一错误,并取得了非常好的效果,完美结合了C和其

    他一些语言。

    这个故事是从维基百科里面直接复制过来的,很多讲Python历史的

    资料里面,也都转载了这一段文字。但是,在我来看,吉多是为了“打

    发时间”而决定开发Python,源自他的这样一段自述:

    Over six years ago,in December 1989,I was looking for

    ahobbyprogramming project that would keep me occupied during the week

    around Christmas.My office(a government-run research lab in

    Amsterdam)would be closed,but I had a home computer,and not much

    else on my hands.I decided to write an interpreter for the new scripting

    language I had been thinking about lately:a descendant of ABC that would

    appeal to UnixC hackers.I chose Python as a working title for the project,being in a slightly irreverent mood(and a big fan of Monty Python's Flying

    Circus).(原文地址:https:www.python.orgdocessaysforeword)

    首先,必须承认,这个哥们儿是一个非常牛的人,此处献上恭敬的

    崇拜。其次,刚刚开始学习Python的朋友,可千万别认为Python是一个可

    以随随便便鼓捣的东西,人家也是站在巨人的肩膀上的。

    第三,牛人在成功之后,往往把奋斗的过程描绘得比较简单。或者

    是出于谦虚,或者是为了让人听起来他更牛。反正,我们看最后结果的

    时候,很难感受过程中的酸甜苦辣。

    不管怎样,吉多·范罗苏姆在那时刻创立了Python,而且,更牛的在

    于他具有现代化的思维——开放,并通过Python社区,吸引来自世界各

    地的开发者,参与Python的建设。在这里,请读者一定要联想到Linux

    和它的创始人林纳斯·托瓦兹。两者都秉承“开放”思想,得到了来自世

    界各地开发者和应用者的欢呼和尊敬。

    请读者向所有倡导“开放”的牛人们表示敬意,是他们让这个世界变

    得更美好,他们以行动诠释了热力学第二定律——“熵增原理”。

    2.Python的现在

    Python现在越来越火了,因为它搭上了“大数据”、“云计算”、“自然

    语言处理”等这些时髦名词的便车。

    网上时常会有一些编程语言排行榜之类的东西,有的初学者常常被

    排行榜所迷惑,总想要学习排列在第一位的,认为排在第一位的编程语

    言需求量大。不管排行榜是怎么编制的,Python虽然没有登上状元、榜

    眼、探花之位,但也不太靠后呀。

    另外一个信息,更能激动一下初学者那颗脆弱的小心脏。

    Dice.com网上对20000名IT专业人士进行调查的结果显示:Java类程

    序员平均工资91060美元;Python类程序员平均工资90208美元。

    Python程序员比Java程序员的平均工资低,但看看差距,再看看两

    者的学习难度,学习Python绝对是一个性价比非常高的投资。

    这么合算的编程语言不学等待何时?

    3.Python的未来Python的未来要靠读者了,你学好了、用好了,未来它就光明了,它的未来在你手里。如图0-1所示为Python创始人吉多·范罗苏姆。

    0.1.2 Python的特点

    很多高级语言都宣称自己是简单的、入门容易的,并且具有普适

    性,但真正能做到这些的,只有Python。有朋友做了一件衬衫,上面写

    着“生命有限,我用Python”,这说明什么?说明Python有着简单、开发

    速度快、节省时间和精力的特点。因为它是开放的,有很多可爱的开发

    者(为开放社区做贡献的开发者是最可爱的人),将常用的功能做好了

    放在网上,谁都可以拿过来使用。这就是Python,这就是开放。图0-1 Python创始人:吉多·范罗苏姆

    恭敬地抄录来自《维基百科》的描述:Python是完全面向对象的语言,函数、模块、数字、字符串都是对

    象,并且完全支持继承、重载、派生、多继承,有益于增强源代码的复

    用性。Python支持重载运算符,因此也支持泛型设计。相对于Lisp这种

    传统的函数式编程语言,Python对函数式设计只提供了有限的支持。有

    两个标准库(functools和itertools)提供了Haskell和Standard ML中久经

    考验的函数式程序设计工具。

    虽然Python可能被粗略地分类为“脚本语言”(Script Language),但实际上一些大规模软件开发项目(例如Zope、Mnet、BitTorrent及

    Google)也都广泛地使用它。Python的支持者较喜欢称它为一种高级动

    态编程语言,原因是“脚本语言”泛指仅做简单程序设计任务的语言,如

    shell script、VBScript等,但其只能处理简单任务的编程语言,并不能与

    Python相提并论。

    Python本身被设计为可扩充的,并非所有的特性和功能都集成到语

    言核心。Python提供了丰富的API和工具,以便程序员能够轻松地使用

    C、C++、Cython来编写扩充模块。Python编译器本身也可以被集成到

    其他需要脚本语言的程序内。因此,很多人还把Python作为一种“胶水

    语言”(glue language)使用,使用Python将其他语言编写的程序进行集

    成和封装。在Google内部的很多项目,例如Google Engine使用C++编写

    性能要求极高的部分,然后用Python或JavaGo调用相应的模块。

    《Python技术手册》的作者马特利(Alex Martelli)说:“2004年,Python已在Google内部使用,Google招募许多Python高手,但在这之前

    就已决定使用Python。他们的目的是尽量使用Python,在不得已时改用

    C++;在操控硬件的场合使用C++,在快速开发时使用Python。”

    可能这里面有一些术语还不是很理解,没关系,只要明白:Python

    是一种很牛的语言,应用简单,功能强大,Google都在使用,这就足够

    了,足够让你下决心学习了。

    0.1.3 Python哲学

    Python之所以与众不同,还在于它强调一种哲学理念:优雅、明

    确、简单。有一段诗歌读起来似乎很玄,但真实反映了Python开发者的

    开发理念:The Zen of Python

    Beautiful is better than ugly.

    Explicit is better than implicit.

    Simple is better than complex.

    Complex is better than complicated.

    Flat is better than nested.

    Sparse is better than dense.

    Readability counts.

    Special cases aren't special enough to break the rules.

    Although practicality beats purity.

    Errors should never pass silently.

    Unless explicitly silenced.

    In the face of ambiguity, refuse the temptation to guess.

    There should be one-- and preferably only one --obvious way to do it.

    Although that way may not be obvious at first unless you're Dutch.

    Now is better than never.

    Although never is often better than “right” now.

    If the implementation is hard to explain, it's a bad idea.

    If the implementation is easy to explain, it may be a good idea.

    Namespaces are one honking great idea -- let's do more of those!

    网上能够看到这段文字的中文译本,读者可以去搜索阅读。0.2 从小工到专家

    这个标题,我借用了一本书的名字——《程序员修炼之道:从小工

    到专家》,并在此特别推荐阅读。

    “从小工到专家”也是很多刚学习编程的朋友的愿望。如何能实现

    呢?《程序员修炼之道:从小工到专家》这本书中,给出了非常好的建

    议,值得借鉴。

    有一个学习Python的朋友曾问我:“书已经看了,书上的代码也运

    行过了,习题也能解答了,但是还不知如何开发一个真正的应用程序,不知从何处下手,怎么办?”

    另外,也遇到过一些刚刚毕业的大学生,从简历上看,相关专业的

    考试分数是不错的(我一般相信那些成绩是真的),但是,一讨论到专

    业问题,常常不知所云,特别是当让他面对真实的工作对象时,表现出

    来的比成绩单差太多了。

    对于上述情况,我一般会武断地下一个结论:练得少。

    要从小工成长为专家,必经之路是要多阅读代码,多调试程序。古

    言“拳不离手,曲不离口”,多练习是成为专家的唯一途径。

    0.2.1 零基础

    有一些初学者,特别是非计算机专业的人,担心自己基础差,不能

    学好Python。诚然,在计算机方面的基础越好,对学习任何一门新的编

    程语言越有利。但如果是“绝对零基础”也不用担心,本书就是从这个角

    度切入来满足你的需要的。凡事总得有一个开始,那么就让本书成为你

    学习编程语言的开始吧。

    就我个人来看,Python是比较适合作为学习编程的入门语言的。美国有不少高校也这么认为,他们纷纷用Python作为编程专业甚至

    是非编程专业的大学生入门语言,如图0-2所示为美国各高校设立的编

    程语言专业。

    图0-2 美国高校设立的编程语言专业

    总而言之,学习Python,你不用担心基础问题。

    0.2.2 阅读代码

    有句话说得好:“读书破万卷,下笔如有神”,这也适用于编程。通

    过阅读别人的代码,“站在巨人的肩膀上”,让自己眼界开阔,思维充

    实。

    阅读代码的最好地方就是:www.github.com。

    如果你还没有账号,请尽快注册,它将是你成为一个优秀程序员的

    起点。当然,不要忘记来follow我,我的账号是:qiwsir。

    阅读代码最好的方法是一边阅读、一边进行必要的注释,这样可以

    梳理对别人代码的认识。然后可以run一下,看看效果。当然,还可以按照自己的设想进行必要修改,然后再run。经过几轮,就可以将别人

    的代码消化吸收了。

    0.2.3 调试程序

    阅读是信息的吸收过程,写作则是信息的加工输出过程。

    要自己动手写程序。“一万小时定律”在编程领域也是成立的,除非

    你天生就是天才,否则,只有通过“一万小时定律”才能成为天才。

    在调试程序的时候,要善于应用网络,看看类似的问题别人是如何

    解决的,不要仅局限于自己的思维范围。利用网络就少不了使用搜索引

    擎,在此特别向那些要想成为专家的小工们说:Google能够帮助你成为

    专家。

    我不相信“三天掌握Python”、“三周成为高手”之类的让人听起来热

    血沸腾、憧憬无限的骗人宣传。如果你通过本书跟我对话,至少说明你

    我都是普通人,普通人要做好一件事情,除了“机缘巧合”遇到贵人之

    外,就要靠自己勤学苦练了,没有捷径,凡是宣传捷径的,大多都是骗

    子。0.3 安装Python

    任何高级语言都需要一个自己的编程环境,这就好比写字一样,需

    要有纸和笔,在计算机上写东西,也需要有文字处理软件,比如各种名

    称的Office类软件。笔和纸以及Office软件,就是写东西的硬件或软件,总之,那些文字只能写在相应的硬件或软件上,才能最后成为一篇文

    章。编程也要有个程序之类的东西,把代码写在上面,才能形成类似文

    章那样的文件——自己编的程序。

    阅读本书的零基础朋友,乃至于非零基础的朋友,不要希望在这里

    学到很多高深的Python语言技巧。重要的是学会一些方法,比如刚才给

    大家推荐的“上网Google一下”,就是非常好的学习方法。互联网的伟大

    之处,不仅仅在于打游戏、看看养眼的照片或者各种视频之类的,我衷

    心希望本书的读者不仅仅把互联网当作娱乐网,还要当作知识网和创造

    网。

    扯远了,拉回来。在学习过程中,遇到一点点疑问都不要放过,思

    考、尝试之后,不管有没有结果,都要Google一下,当然,要做到这一

    点,需要有点技术,这点技术对于立志于成为编程专家的读者来说是必

    须要掌握的。如果阅读到这里,你还没有理解,那说明的确是我的读

    者:零基础。

    《辟邪剑谱》和《葵花宝典》这两本盖世武功秘籍,对练功者提出

    了一个较高的要求:欲练神功,挥刀自宫。

    学Python,如果要达到比较高的水平,其实不用自宫(如果读者真

    的要以此明志,该行为结果与本书的作者和出版机构无关,纯属个人行

    为。若读者尚未成年,请在法定监护人的监护下阅读本书,特此声

    明)。但是,需要在你的计算机中安装一些东西,并且这个过程有时比

    较耗费时间。

    所需要安装的东西,都在这个页面里面:

    www.python.orgdownloads。www.python.org是Python的官方网站,如果你的英语非常好,那么

    阅读该网站,可以获得非常多的收获。

    在下载页面里面,显示出Python目前有两大版本:Python 3.x.x和

    Python 2.7.x。可以说,Python 3是未来,它比Python 2.7有进步。但是,现在还有一些东西没有完全兼容Python 3,所以,本书在讲解中以

    Python 2.7为主,兼顾Python 3.x。一般而言,如果学了Python 2.7,再学

    习Python 3就很容易,因为两者只是某些地方的变化。请读者不要纠结

    于是学习Python 2还是学习Python 3这种无聊的问题,如果两个差别达到

    让你学了而这个无法使用那个,这将是Python的灾难。绝顶聪明的

    Python创造者和维护者们,绝对不会允许这样的事情出现。

    0.3.1 Ubuntu系统

    你的计算机是什么操作系统的?如果是Linux的某个发行版,比如

    Ubuntu,那么就跟我同道了。如果是iOS,也一样,因为都是UNIX麾下

    的,与在Ubuntu中的安装过程大同小异。只是Widows有点另类了。

    但没关系,Python就是跨平台的,它可以在任何系统下进行编程,用它写出来的程序也可以运行在任何操作系统中。

    但是,我个人推荐使用LinuxUNIX系列的操作系统。

    正常情况下,只要安装了Ubuntu这个操作系统,就已经安装好了

    Python的编程环境。你只需要打开Shell,然后输入Python,单击“回

    车”之后就会看到如下内容:

    python

    Python 2.7.6 (default, Nov 13 2013, 19:24:16)

    [GCC 4.6.3] on linux2

    Type help, copyright, credits or license for more information.

    >>>

    如果没有该编程环境,就需要安装了,一种最简单的方法:

    sudo apt-get install python

    还有另外一种比较麻烦的方法,但似乎能炫耀一下自己的水平,方法如下。

    (1)到官方网站下载源码。比如:

    wget http:www.python.orgftppython2.7.8Python-2.7.8.tgz

    (2)解压源码包

    tar -zxvf Python-2.7.8.tgz

    (3)编译

    cd Python-2.7.8 .configure --prefix=usrlocal

    makesudo make install

    这里指定了安装目录usrlocal。如果不指定,可以使用默认的,直

    接运行.configure即可。

    安装好之后,进入Shell,输入Python,就会看到结果。我们将那个

    带有“>>>”的界面称之为“Python的交互模式”。

    0.3.2 Windows系统

    到下载页面里找到Windows安装包下载,比如下载了这个文件:

    python-2.7.8.msi。然后完成安装。

    特别注意,安装完之后,需要检查系统环境变量是否有Python,如

    果没有,就设置一下。

    以上搞定后,在cmd中,输入“python”,得到与前面类似的结果,就说明已经安装好了。

    0.3.3 Mac OS X系统

    其实根本就不用再写怎么安装Mac OS X系统了,因为用Mac OS X的朋友,肯定是高手中的高高手了,至少我一直很敬佩那些用Mac OS

    X并坚持没有更换为Windows的人。

    所幸的是用苹果电脑的就不用安装了,因为里面一定预装好了,拿

    过来就可以直接用。

    如果按照以上方法顺利安装成功,只能说明幸运。如果没有安装成

    功,则是提高自己的绝佳机会,因为只有遇到问题才能解决问题,才能

    知道更深刻的道理,不要怕,使用Google,它能帮助你解决问题。当

    然,也可以加入QQ群或者通过微博问我。0.4 集成开发环境(IDE)

    安装好Python之后,就可以进行开发了。按照惯例,第一行代码总

    是:Hello World。

    0.4.1 值得纪念的时刻:Hello world

    不管你使用的是什么操作系统,总之肯定能够找到一个地方运行

    Python,进入到交互模式,像下面一样:

    Python 2.7.6 (default, Nov 13 2013, 19:24:16)

    [GCC 4.6.3] on linux2

    Type help, copyright, credits or license for more information.

    >>>

    在“>>>”后面输入printHello,World,并按回车键,下面是见证奇

    迹的时刻。

    >>> print Hello, World

    Hello, World

    如果你从来不懂编程,那么从这一刻起,就跨入了程序员行列;如

    果已经是程序员,那么就温习一下当初的惊喜吧!

    “Hello,World”是你用代码向这个世界打招呼了。

    每个程序员,都曾经经历过这个伟大时刻,不经历这个伟大时刻的

    程序员不是伟大的程序员。为了纪念这个伟大时刻,理解其伟大之所

    在,下面执行分解动作:

    说明:在下面的分解动作中,用到了符号“”,这个符号在Python

    编程中表示注释。所谓注释,就是在计算机中不执行那句话,只是为了

    说明某行语句表达什么意思,是给计算机前面的人看的。特别提醒,在编程实践中,注释是必须的,尽管很多人要求代码要具有可读性,但必

    要的注释也是少不了的。请牢记:程序在大多数情况下是给人看的,只

    是偶尔让计算机执行一下。

    看到“>>>”符号,表示Python做好了准备,等待你向它发出指令,让它做事情。

    >>>

    print,意思是打印。在这里也是这个意思,是要求Python打印东

    西。

    >>> print

    Hello,World是打印的内容,注意,双引号是英文状态下的。引

    号不是打印内容,它相当于一个包裹,把打印的内容包起来,统一交给

    Python。

    >>> print Hello, World

    上面命令执行的结果。Python接收到你要求它所做的事情:打印

    Hello,World,于是它就老老实实地执行这个命令,丝毫不走样。

    Hello, World

    在Python中,如果进入了上面的样式,就是进入了“交互模式”。这

    是非常有用而且简单的模式,便于我们进行各种学习和探索,随着学习

    的深入,你将更加觉得它魅力四射。

    笑一笑:有一个程序员,感觉自己书法太烂了,于是立志继承光荣

    文化传统,购买了笔墨纸砚。在某天开始练字,将纸铺好,拿起笔蘸足

    墨水,挥毫在纸上写下了两个大字:Hello World。

    虽然进入了程序员序列,但是,如果程序员用这个工具仅仅是打

    印“Hello,World”,又怎能用“伟大”来形容呢?况且这个工具也太简陋

    了。你看美工妹妹用的Photoshop,行政妹妹用的Word,出纳妹妹用的

    Excel,就连坐在老板桌后面的那个家伙也在用PPT播放自己都不相信的

    新理念呢,难道我们伟大的程序员,就用这么简陋的工具来写旷世代码吗?

    当然不是。软件是谁开发的?程序员。程序员肯定会先为自己打造

    好用的工具,这也叫作“近水楼台先得月”。

    IDE就是程序员的工具。

    0.4.2 集成开发环境概述

    IDE的全称是:Integrated Development Environment,简称IDE,也

    称为Integration Design Environment或Integration Debugging

    Environment,翻译成中文叫作“集成开发环境”,它是一种辅助程序员开

    发用的应用软件。

    维基百科这样对IDE定义:

    IDE通常包括程序语言编辑器、自动建立工具和除错器。有些IDE

    包含编译程序和直译器,如微软的Microsoft Visual Studio,有些则不包

    含,如Eclipse、SharpDevelop等,这些IDE是通过调用第三方编译器来

    实现代码的编译工作的。有时IDE还会包含版本控制系统和一些可以设

    计图形用户界面的工具。许多支持面向对象的现代化IDE还包括类别浏

    览器、对象查看器、对象结构图。虽然目前有一些IDE支持多种程序语

    言(例如Eclipse、NetBeans、Microsoft Visual Studio),但是一般而

    言,主要还是针对特定的程序语言而量身打造(例如Visual Basic)。

    如图0-3所示是微软提供的名字叫作Microsoft Visual Studio的IDE,用C进行编程的程序员都用它。图0-3 名叫Microsoft Visual Studio的IDE

    如图0-4所示是在苹果电脑中出现的名叫XCode的IDE。

    要想了解更多IDE的信息,推荐阅读维基百科中的词条。

    英文词条:Integrated development environment

    中文词条:集成开发环境图0-4 名叫XCode的IDE

    0.4.3 Python的IDE

    用Google搜索一下:Python IDE,会发现能够进行Python编程的IDE

    还真不少。东西一多就容易无所适从,所以有不少人都问用哪个IDE

    好。可以看看下面链接里的内容:

    http:stackoverflow.comquestions81584what-ide-to-use-for-python。

    顺便推荐一个非常好的与开发相关的网站:stackoverflow.com。在

    这里可以提问,可以查看答案。如果有问题,一般先在这里查找,大多

    数情况都能找到非常满意的结果,且有很大启发。

    那么作为零基础的学习者,用哪个IDE好呢?既然是零基础,就别

    瞎折腾了,就用Python自带的IDLE,原因就是:简单,虽然它比较简

    陋。在Windows中,通过“开始”菜单→“所有程序”→“Python

    2.x”→“IDLE(Python GUI)”来启动IDLE。启动之后,看到如图0-5所

    示的界面。

    图0-5 IDLE界面

    注意:若看到的界面显示版本与这个图不同,则说明安装的版本不

    同,但大致模样差不多。

    其他操作系统的用户,也都能在启动IDLE这个程序之后,出现与

    上面一样的图。

    这里其实是Python的交互模式编程环境。

    当然还有一个文本环境,读者可以在File菜单中新建一个文件,即

    进入文本编辑环境。

    除了这个自带的IDE,还有很多其他的IDE,列出来,供喜欢折腾

    的朋友参考。

    PythonWin:是Python Win32 Extensions(半官方性质的Python for

    win32增强包)的一部分,也包含在ActivePython的Windows发行版

    中。如其名字所言,只针对Win32平台。

    MacPython IDE:MacPythonIDE是Python的Mac OS发行版内置的

    IDE,可以看作是PythonWin的Mac对应版本,由Guido的哥哥Just

    van Rossum编写。

    Emacs和Vim:Emacs和Vim号称是这个星球上最强大的文本编辑器,对于许多程序员来说是万能IDE的不二选择。

    Eclipse+PyDev:Eclipse是新一代的优秀泛用型IDE,虽然是基于

    Java技术开发的,但出色的架构使其具有不逊于Emacs和Vim的可

    扩展性,现在已经成为了许多程序员最爱的瑞士军刀。

    磨刀不误砍柴工,IDE已经有了,伟大程序员就要开始从事伟大的

    编程工作了。第1章 基本的对象类型

    在Python中,“万物皆对象”,在一开始就这么提出来,如果你没有

    理解,也不用为此吃不好、睡不好,就当听了一个新名词,因为对

    于“对象”的理解,可以说要贯穿全书,甚至贯穿你的代码生涯。随着实

    践的增多,对于“万物皆对象”的领悟会逐渐深化。

    什么是对象?现在暂时不给出定义,一定要等到时机成熟的时候给

    出定义才能理解。

    如果要准确描述Python对象,需要从“身份、类型、值”三个维度来

    描述,这三个维度也构成了一个对象的特征。至于怎样从上述三个维度

    来描述对象,本章将以Python中基本的对象类型为例进行说明。如果换

    一种说法,也可以理解为本章将带领你了解Python中的某些常用的和基

    本类型的对象。1.1 数字

    现在更多人把计算机叫作电脑,英文是Computer。只要提到它,普

    遍都会想到它能够比较快地做加减乘除,甚至乘方、开方等各种数学运

    算。

    有一篇名为《计算机前世》的文章(参见:

    http:www.flickering.cn),这样讲到:

    先来看看计算机(Computer)这个词是怎么来的。英文学得好的小

    伙伴看到Computer,第一反应是:“compute-er”,应该是个什么样的人

    吧,对,“做计算的人”。叮咚!恭喜你答对了。最先被命名为Computer

    的确实是人。也就是说,电子计算机(与早期的机械计算机)被赋予这

    个名字是因为他们执行的是被分配到的人的工作。“计算机”原来是工作

    岗位,它被用来定义一个工种,其任务是执行计算,诸如导航表、潮汐

    图表、天文历书和行星的位置要求等的重复计算,从事这个工作的人就

    是Computer,而且大多是女神。

    原文还附有如图1-1所示的图片。

    所以,以后要用第三人称来称呼Computer,请用She(她)。现在

    你明白为什么程序员中那么多“他”了吧,因为Computer是“她”。图1-1 从事Computer工作的人

    1.1.1 数字

    在Python中,对数的规定比较简单,达到了小学数学水平即可理

    解。

    首先,进入到Python的交互模式中,不管是什么操作系统,相信你

    总能找到那个交互模式。然后模仿下面的操作:

    >>> 3

    3

    >>> 3333333333333333333333333333333333333333

    3333333333333333333333333333333333333333L

    >>> 3.222222

    3.222222

    在交互模式下,如果输入3,就显示了3,这样的数称为整数,这个

    称呼和小学数学一样。

    当输入一个比较大的整数时,Python会自动将这个大整数进行转

    换,转换的结果是一个“长整数”类型,为了表示它,会在其末尾显示一个L。由于这个操作是Python自动完成的,所以在现在的Python中,没

    有单独将“长整数”作为一个类型。

    3.222222在数学里面称为小数,这里依然可以这么称呼,不过就像

    很多编程语言一样,习惯称之为“浮点数”。至于这个名称的由来,也是

    有点说道的,有兴趣可以搜索一下。

    上述举例中都无符号(或者说是非负数),如果要表示负数,跟数

    学中的表示方法一样,前面填上负号即可。

    值得注意的是,我们这里说的都是十进制的数。

    除了十进制,还有二进制、八进制、十六进制都是在编程中可能用

    到的,这些知识不作为本书讲解的内容,读者要了解,可以寻找相关书

    籍,或者去网上搜索。

    每个数字在Python中都是一个对象,比如前面输入的3就是一个对

    象。每个对象,在内存中都有自己的一个地址,这就是它的身份。

    >>> id(3)

    140574872

    >>> id(3.222222)

    140612356

    >>> id(3.0)

    140612356

    >>>

    用内建函数id可以查看每个对象的内存地址,即身份。

    内建函数,英文为built-in Function,读者根据名字也能猜个八九不

    离十了。不错,就是Python中已经定义好的内部函数。

    以上三个不同的数字是三个不同的对象,具有三个不同的内存地

    址。特别要注意,在数学上,3和3.0是相等的,但是在这里,它们是不

    同的对象。

    用id得到的内存地址是只读的,不能修改。

    了解了“身份”,再来看“类型”,也有一个内建函数供使用,即

    type。>>> type(3)

    

    >>> type(3.0)

    

    >>> type(3.222222)

    

    说明3是整数类型(Interger);则告诉我们

    该对象是浮点型(Floating point real number)。与id的结果类似,type得到的结果也是只读的。

    至于对象的值,在这里就是对象本身了。

    看来对象也不难理解。

    请保持自信,继续。

    1.1.2 变量

    仅仅写出“3、4、5”是远远不够的,在编程中,经常要用到“变

    量”和“数”(严格来讲是对象)建立起对应关系。例如:

    >>> x = 5

    >>> x

    5

    >>> x = 6

    >>> x

    6

    在这个例子中,x=5就是在变量x和数5之间建立了对应关系,接着

    又建立了x与6之间的对应关系。我们可以看到,x先“是”5,后

    来“是”6。

    在Python中,有这样一句话是非常重要的:对象有类型,变量无类

    型。怎么理解呢?

    对象的类型,可以使用type来查看,前面已经演示了。

    当在Python中写入了5、6,Computer就自动在其内存中某个地方建

    立了这两个对象,就好比建造了两个雕塑,一个形状似5,一个形状似6,这两个对象的类型就是Int.

    那个x就好比是一个标签,当x=5时,就是将x这个标签拴在了5上,通过这个x,就顺延看到了5,于是在交互模式中,“>>>x”输出的结果就

    是5,给人的感觉似乎是x就是5,而事实是x这个标签贴在5上面。同样

    的道理,当x=6时,标签就换位置了,贴到6上面。

    所以,这个标签x没有类型之说,它不仅可以贴在整数类型的对象

    上,还能贴在其他类型的对象上,比如后面会介绍到的str(字符串)类

    型的对象等。

    Python中变量的这个特点(即可以四处乱贴的标签)非常重要,它

    没有类型。

    1.1.3 简单的四则运算

    读者可以在交互模式中复习一下小学数学中的四则运算,并且报告

    给你小学数学老师,他(她)当初煞费苦心的教育成果在这里得到了应

    用。

    >>> 2+5

    7

    >>> 5-2

    3

    >>> 102

    5

    >>> 52

    10

    >>> 105+1

    3

    >>> 23-4

    2

    上面的运算中,分别涉及四个运算符号:加(+)、减(-)、乘

    ()、除()

    另外,我相信读者已经发现了一个重要的公理:

    计算机中的四则运算和小学数学中学习过的四则运算规则是一样的要不怎么说人是高等动物呢,自己发明的东西,一定要继承自己已

    经掌握的知识,别跟自己的历史过不去。伟大的科学家们,在当初设计

    计算机的时候就想到我们现在学习的需要了,一定不能让后世子孙再学

    新的运算规则,就用小学数学里面的好了。感谢那些科学家先驱者,泽

    被后世。

    下面计算3个算术题,看看结果是什么:

    4 + 2

    4.0 + 2

    4.0 + 2.0

    你可能愤怒了,这么简单的题目,就不要劳驾计算机了,太浪费

    了。

    别着急,还是要运算一下,然后看看结果有没有不一样,要仔细观

    察哦。

    >>> 4+2

    6

    >>> 4.0+2

    6.0

    >>> 4.0+2.0

    6.0

    不一样的地方是:第一个公式结果是6,这是一个整数;后面两个

    是6.0,这是浮点数。

    计算机做一些四则运算是不在话下的,但是,有一个问题请务必注

    意:在数学中,整数是可以无限大的,但是在计算机中,整数不能无限

    大。

    因此,就会有某种情况出现,就是参与运算的数或者运算结果超过

    了计算机中最大的数了,这种问题称之为“整数溢出问题”。

    1.1.4 整数溢出问题

    在网上能够找到很多专门讨论“整数溢出”问题的文章。在某些高级编程语言中,整数溢出是必须正视的,但是,在Python

    里面就无需忧愁了,原因就是Python为我们解决了这个问题,它支

    持“无限精度”的整数,所以,不用考虑整数溢出的问题,Int类型与任意

    精度的Long整数类可以无缝转换,超过Int范围的情况都将转换成Long

    类型。

    体验一下大整数:

    >>> 1234567898709876543211223434455676788900988761233455667789990099876543332387665443345566

    152278477193527562870044352587576277277562328362032444339019158937017801601677976183816L

    多么幸运呀,Python做了如此精妙的安排,免除了麻烦,所以选择

    学习Python就是珍惜光阴。

    你还可以在交互模式下计算2的1000次幂,计算方法是:

    >>> 2 1000

    看看结果是什么?你会感到惊喜的。

    上面计算结果的数字最后有一个L,表示这个数是一个长整数,你

    不用管它,反正是Python为我们搞定了大整数问题。1.2 除法

    用单独一个章节来说明除法,就是因为它常常会带来麻烦,不仅

    Python会这样,很多高级语言都如此。

    1.2.1 整数与整数相除

    进入Python交互模式之后,练习下面的运算:

    >>> 2 5

    0

    >>> 2.0 5

    0.4

    >>> 2 5.0

    0.4

    >>> 2.0 5.0

    0.4

    看到了吗?麻烦出来了(这是在Python 2.x中),按照数学运算,以上四个运算结果都应该是0.4。但我们看到第一个结果居然是0。

    Why?

    在Python(严格说是Python 2.x中,Python3会有所变化)里面有一

    个规定,像25这样的除法要取整(就是去掉小数,但不是四舍五

    入)。2除以5,商是0(整数),余数是2(整数)。如果用这种形式:

    25,那么计算结果就是商那个整数。或者可以理解为:整数除以整

    数,结果是整数(商)。

    比如:

    >>> 5 2

    2

    >>> 7 2

    3

    >>> 8 2

    4再次提醒:得到是商(整数),而不是得到含有小数位的结果再通

    过“四舍五入”得到整数。例如:52,得到的商是2,余数是1,最终

    52=2,并不是对结果进行四舍五入得到3。

    1.2.2 浮点数与整数相除

    “浮点数与整数相除”用一种貌似严格的语言表述:

    假设:x除以y。其中x可能是整数,也可能是浮点数;y可能是整

    数,也可能是浮点数,但两者之中至少有一个是浮点数。

    出结论之前,还是先在交互模式中做实验:

    >>> 9.0 2

    4.5

    >>> 9 2.0

    4.5

    >>> 9.0 2.0

    4.5

    >>> 8.0 2

    4.0

    >>> 8 2.0

    4.0

    >>> 8.0 2.0

    4.0

    就如同做物理、化学实验一样,仔细观察上面的实验结果,能得出

    什么结论?

    不管是被除数还是除数,只要有一个数是浮点数,结果就是浮点

    数。

    然而,下面的实验可能又让你有点糊涂了:

    >>> 10.0 3

    3.3333333333333335

    这个是不是就有点搞怪了?按照数学知识,应该是3.33333...,后面

    是3的循环了,那么你的计算机就停不下来了,满屏都是3。为了避免这

    个,Python武断终结了循环,但是,可悲的是没有按照“四舍五入”的原

    则终止。当然,还会有更奇葩的出现:>>> 0.1 + 0.2

    0.30000000000000004

    >>> 0.1 + 0.1 - 0.2

    0.0

    >>> 0.1 + 0.1 + 0.1 - 0.3

    5.551115123125783e-17

    >>> 0.1 + 0.1 + 0.1 - 0.2

    0.10000000000000003

    越来越糊涂了,为什么Computer姑娘在计算这么简单的问题上,如

    此糊涂了呢?

    不是Computer姑娘糊涂,她依然冰雪聪明。

    原因在于十进制和二进制的转换上,Computer姑娘用的是二进制进

    行计算,上面的例子中,我们输入的是十进制,就要把十进制的数转化

    为二进制,然后再计算。但是,在转化中,浮点数转化为二进制,就出

    问题了。

    例如十进制的0.1,转化为二进制是:

    0.0001100110011001100110011001100110011001100110011...

    也就是说,转化为二进制后,不会精确等于十进制的0.1。同时,计算机存储的位数是有限制的,所以,就出现了上述现象。

    这种问题不仅仅在Python中有,所有支持浮点数运算的编程语言都

    会遇到。

    明白了问题原因,怎么解决呢?就Python的浮点数运算而言,大多

    数计算机每次计算误差不超过2的53次方分之一。对于大多数任务这已

    经足够了,但是要在心中记住这不是十进制算法,每个浮点数计算可能

    会带来一个新的舍入错误。

    一般情况下,只要简单地将最终显示的结果用“四舍五入”到所期望

    的十进制位数,就会得到期望的最终结果。

    对于需要非常精确的情况,可以使用decimal模块(关于“模块”,后

    面会介绍,这里暂存),它实现的十进制运算适合高精度要求的应用。

    另外fractions模块支持另外一种形式的运算,它实现的运算基于有理数

    (因此像13这样的数字可以精确地表示)。最高要求则是使用由SciPy

    提供的Numerical Python包和其他用于数学和统计学的包。列出这些东西,仅仅是让读者明白,问题已经解决,并且方式很多。

    1.2.3 引用模块解决除法问题

    Python之所以受人欢迎,一个很重重要的原因就是“轮子”多,当然

    这是比喻,就好比你要跑得快,怎么办?光天天练习跑步也是不行的,还要用轮子。找辆自行车,就快了很多,若还嫌不够快,再换电瓶车、汽车、高铁……反正可以供你选择的很多。但是,这些让你跑得快的东

    西,多数不是你自己造的,是别人造好了你来用。甚至两条腿也是感谢

    父母恩赐。正是因为轮子多,可以选择的多,就可以有各种不同的速度

    享受了。

    轮子是人类伟大的发明。

    Python就是这样,有各种“轮子”供我们选用。只不过那些“轮子”在

    Python里面的名字不叫自行车、汽车,而叫“模块”,有的还叫

    作“库”、“类”。

    怎么用?可以通过以下两种形式。

    形式1:import module-name。import后面跟空格,然后是模块名

    称,例如:import os。

    形式2:from module1 import module11。module1是一个大模块,里

    面还有子模块module11,只想用module11,就这么写。

    找一个解决除法问题的轮子:

    >>> from __future__ import division

    >>> 5 2

    2.5

    >>> 9 2

    4.5

    >>> 9.0 2

    4.5

    >>> 9 2.0

    4.5

    引用了模块之后再做除法,那么不管什么情况,都能得到浮点数的结果了。

    这就是“轮子”的力量。

    1.2.4 余数

    前面计算52的时候,商是2,余数是1

    余数怎么得到?在Python中(其实大多数语言也如此),用%符号

    来取得两个数相除的余数。

    实验下面的操作:

    >>> 5 % 2

    1

    >>> 6 % 4

    2

    >>> 5.0 % 2

    1.0

    利用符号“%”可以得到两个数(可以是整数,也可以是浮点数)相

    除的余数。

    除了利用“%”符号之外,还可以使用内建函数,完成同样的工作。

    >>> divmod(5,2) 表示5除以2,返回了商和余数

    (2, 1)

    >>> divmod(9,2)

    (4, 1)

    >>> divmod(5.0,2)

    (2.0, 1.0)

    内建函数divmod返回的是两个值,这两个值在一个圆括号内,圆

    括号内的数字第一个表示商,第二个表示余数。

    1.2.5 四舍五入

    “四舍五入”在运算中是经常遇到的,按照我们已经对Python的理解,其应该提供一个简单的方法。的确是,有一个内建函数:round。

    >>> round(1.234567, 2)

    1.23

    >>> round(1.234567, 3)

    1.235

    >>> round(10.03, 4)

    3.3333

    在round中的第二个数,表示要保留的小数位数,返回值是一个四

    舍五入之后的数值。

    简单吧?越简单的时候,越要小心,当你遇到下面的情况,就会有

    点儿怀疑:

    >>> round(1.2345,3)

    1.234 应该是:1.235

    >>> round(2.235,2)

    2.23 应该是:2.24

    哈哈,我发现了Python的一个Bug,太激动了。

    别那么激动,如果真的是Bug,还这么明显,是轮不到我的。为什

    么?具体解释看这里,下面摘录官方文档中的一段话:

    Note:The behavior of roundfor floats can be surprising:for example,round(2.675,2)gives 2.67 instead of the expected 2.68.This is not a

    bug:it’s a result of the fact that most decimal fractions can’t be represented

    exactly as a float.See Floating Point Arithmetic:Issues and Limitations for

    more information.

    原来真的轮不到我。归根到底还是浮点数中的十进制转化为二进制

    惹的祸。

    除法的问题似乎要到此结束了,其实远远没有,不过,作为初学

    者,至此即可。1.3 常用数学函数和运算优先级

    在数学之中,除了加减乘除四则运算之外(这是小学数学),还有

    其他更多的运算,比如乘方、开方、对数运算等,要实现这些运算,需

    要用到Python中的一个模块:math。

    1.3.1 使用math模块

    math模块是Python标准库中的,所以不用安装就可以直接使用。使

    用方法是:

    >>> import math

    用import就将math模块引用过来了,下面就可以使用这个模块提供

    的工具了。比如,要得到圆周率:

    >>> math.pi

    3.141592653589793

    这个模块都能做哪些事情呢?可以用下面的方法看到:

    >>> dir(math)

    ['__doc__', '__name__', '__package__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']

    dir(module)是一个非常有用的指令,可以通过它查看任何模块中

    所包含的工具。从上面的列表中就可以看出,在math模块中,可以计算

    正弦sin、余弦cos、开平方0sqrt等函数。

    这些函数是math中提供的,不需要我们编写,可以拿过来就用。比

    如计算乘方,可以使用pow函数。但是,怎么用呢?

    Python是一个非常周到的“姑娘”,她早就提供了一个命令,让我们

    来查看每个函数的使用方法。>>> help(math.pow)

    在交互模式下输入上面的指令,然后回车,看到下面的信息:

    Help on built-in function pow in module math:

    pow(...)

    pow(x, y)

    Return xy (x to the power of y).

    这里非常清楚地告诉了我们math中的pow函数的使用方法和相关说

    明。

    由于是第一次用到help,有必要将结果详细解释一番。

    1)第一行意思是说这里是math模块的内建函数pow的帮助信息

    (built-in称之为内建函数,是说这个函数是Python默认的)。

    2)第三行表示这个函数的参数,有两个,也是函数的调用方式。

    3)第四行是对函数的说明,返回xy的结果,并且在后面解释了

    xy的含义。

    最后,按q键返回到Python交互模式。

    当然,也看到了一个额外的信息,就是pow函数和xy是等效的,都是计算x的y次方。

    >>> 4 2

    16

    >>> math.pow(4,2)

    16.0

    >>> 4 2

    8

    特别注意,42和42是有很大区别的。

    用help函数,可以查看math模块中任何一个函数的使用方法。

    下面是几个常用的math模块中函数举例,你可以结合自己调试的进

    行比照。

    >>> math.sqrt(9)3.0

    >>> math.floor(3.14)

    3.0

    >>> math.floor(3.92)

    3.0

    >>> math.fabs(-2) 等价于abs(-2)

    2.0

    >>> abs(-2)

    2

    >>> math.fmod(5,3) 等价于5%3

    2.0

    >>> 5 % 3

    2

    在上面的内容中,读者除了要了解math模块外,还要体会对后续学

    习非常有帮助的内建函数dir和help。

    1.3.2 两个函数

    下面两个也是常用的数学函数。

    1.求绝对值

    >>> abs(10)

    10

    >>> abs(-10)

    10

    >>> abs(-1.2)

    1.2

    2.四舍五入

    >>> round(1.234)

    1.0

    >>> round(1.234, 2)

    如果不清楚这个函数的用法,可以使用下面的方法看帮助信息。

    >>> help(round)

    Help on built-in function round in module __builtin__:

    round(...)

    round(number[, ndigits]) -> floating point number

    Round a number to a given precision in decimal digits (default 0 digits).

    This always returns a floating point number. Precision may be negative.1.3.3 运算优先级

    从小学数学开始,就研究运算优先级的问题,比如在四则运算

    中“先乘除,后加减”,说明乘法和除法的优先级要高于加法和减法。对

    于同一级别的,就按照“从左到右”的顺序进行计算。

    下面的表格中列出了Python中的各种运算的优先级顺序。不过,就

    一般情况而言,不需要记忆,完全可以按照数学中的运算规则去理解,因为人类既然已经发明了数学,在计算机中进行的运算就不需要重新编

    写一套新规范了,只需要符合数学中的运算规则即可。

    在此读者只需要看个大概、有个印象即可,可以一边向后阅读,一

    边回来翻阅,或者在用到的时候来这里查看。如表1-1所示。

    表1-1 运算规则

    最后要提及的是运算中的绝杀:括号。只要有括号,就先计算括号

    里面的。这是数学中的共识,无需解释。1.4 第一个简单的程序

    通过对四则运算的学习,已经初步接触了Python中的内容,如果是

    零基础的学习者,可能会有点迷惑:难道敲几个命令,然后看到结果,就算编程了?这也不是那些能够自动运行的程序啊?

    到目前为止,还不能算编程,只能算会用一些指令(或者叫作命

    令)来做点儿简单的工作。

    少安毋躁,下面就开始编写一个真正的、简单的程序。

    1.4.1 程序

    下面一段内容是关于程序的概念,内容来自维基百科:

    计算机程序(Computer Program)是指一组指示计算机或其他具有

    信息处理能力、装置每一步动作的指令,通常用某种程序设计语言编

    写,运行于某种目标体系结构上。打个比方,一个程序就像一个用汉语

    (程序设计语言)写下的红烧肉菜谱(程序),用于指导懂汉语和烹饪

    手法的人(体系结构)来做这个菜。

    通常,计算机程序要经过编译和链接而成为一种人们不易看清而计

    算机可解读的格式,然后运行。未经编译就可运行的程序,通常称之为

    脚本程序(script)。

    简而言之,程序就是指令的集合。但是,有的程序需要编译,有的

    不需要。Python编写的程序就不需要编译,因此她也被称之为解释性语

    言,编程出来的程序叫作脚本程序。

    某些程序员认为“编译型语言比解释性语言高价”,这是错误的。不

    要认为编译的程序好,不编译的就不好;也不要认为编译的程序属

    于“高端”,不编译的就属于“低端”,这是毫无根据的。不争论,用得妙就是好。

    1.4.2 用IDE编程

    在实践中,每个人都有自己喜欢的IDE。所以,也请读者在学习中

    找到自己喜欢的IDE,Python有一个默认IDE,当打开了Python Shell之后,通过“File-

    >New window”打开一个文本编辑界面。如图1-2所示。在这个界面中就

    可以写程序了。

    在这个界面看不到用于输入指令的提示符“>>>”,这个界面有点像

    记事本。说对了,其本质上就是一个记事本,只能输入文本,不能直接

    在里面贴图片。如图1-3所示。

    图1-2 文本编辑界面图1-3 输入界面

    1.4.3 Hello,World

    “Hello,World”是面向世界的标志,所以,任何程序的第一句一定

    要写这个,因为程序员是面向世界的,绝对不畏缩在某个局域网内。

    直接上代码,就这么一行即可。

    print Hello,World

    如图1-4所示为代码样式。

    程序就是指令的集合。现在,这个程序里面就一条指令,一条指令

    也可以成为集合。

    注意观察,单击Run菜单,在下拉列表里面选择“Run Module”,如

    图1-5所示。图1-4 代码样式

    图1-5 单击菜单选项

    然后弹出对话框,要求把这个文件保存,将文件保存到一个位置,一定要记住这个位置,并且取个文件名,文件名以.py为扩展名。

    都做好之后,单击“确定”按钮,就会发现在另外一个带有“>>>”的

    界面中,就自动出来了“Hello,World”两个大字。

    成功了吗?成功了也别兴奋,因为还没有到庆祝的时候。

    在这种情况下,我们依然是在IDE的环境中实现了刚才那段程序的

    自动执行,如果脱离这个环境呢?

    关闭IDLE,打开shell,或者打开cmd,通过命令的方式,进入到你

    刚才保存的文件目录。这个文件夹里面就一个文件,名为105.py,就是刚才保存的那个文

    件。

    然后在这个shell里面输入:python 105.py。

    上面这句话的含义就是:告诉计算机运行一个Python语言编写的程

    序,程序文件的名称是105.py

    我的计算机我做主,于是它乖乖地执行了这条命令。如下图:

    还在沉默?可以欢呼了。因为你在程序员道路上迈出了伟大的第二

    步(思考:什么时候迈出的第一步?)。

    1.4.4 解一道题目

    题目:请计算19+2482

    读者先自己仰望天空(或者天花板)冥想一下大概如何写,然后继

    续。

    代码:

    !usrbinenv python

    coding:utf-8

    请计算:19+2482

    a = 19 + 2 4 – 8 2

    print a

    提醒初学者,不要复制这段代码,要一个字一个字地敲进去,然后

    保存(我保存的文件名是:105-1.py)。

    在shell或者cmd中,执行:python文件名.py。

    执行结果如下图:

    好像还是比较简单。

    下面对这个简单程序进行解释。

    !usrbinenv python

    这一行是必须写的,它能够引导程序找到Python的解释器(或者叫

    解析器、直译器)。也就是说,不管这个文件保存在什么地方,这个程

    序都能执行,而不用指定Python的安装路径。

    解释器(Interpreter),是一种电脑程序,能够把高级编程语言逐

    行直接翻译运行。解释器不会一次性把整个程序翻译出来,只像一

    位“中间人”,每次运行程序时都要先转成另一种语言再运行,因此解释

    器的程序运行速度比较缓慢。它每翻译一行程序语句就立刻运行,然后

    再翻译下一行,再运行,如此不停地进行下去。

    解释器的好处是它消除了编译整个程序的负担,但也会让运行时的

    效率打折扣。相对地,编译器并不运行程序或源代码,而是一次将其翻

    译成另一种语言,如机器码,以供多次运行而无须再编译。其制成品无

    须依赖编译器而运行,程序运行速度比较快。(来自《维基百科》)

    coding:utf-8

    这一行是告诉Python,本程序采用的编码格式是utf-8,什么是编

    码?什么是utf-8?这是一个比较复杂且有历史的问题,此处暂不讨论。只有有了上面这句话,在后面的程序中才能写汉字,否则就会报错。

    请计算:19+24?82

    这一行是让人看的,而计算机看不懂。在Python程序中(别的编程

    语言也是如此),要写所谓的注释,就是对程序或者某段语句的说明文

    字,这些文字在计算机执行程序的时候被计算机姑娘忽略,但是,必要

    的注释又是必不可少的,正如前面说的那样,程序在大多数情况下是给

    人看的,注释就是帮助人理解程序的。当然,本程序中的注释是不必要

    的,纯粹是为了说明注释而写。

    写注释的方式有两种,一种是单行注释,用“”开头,另一种是多

    行注释,用一对“'''”(三个单引号)包裹起来。

    用开头的注释,可以像下面这样来写:

    请计算:19+2482

    这种注释通常写在程序中的某个位置,比如某个语句的前面或者后

    面。计算机也会忽略这种注释的内容,因为只是给人看的。

    一般在程序的开头部分都要写点东西,主要是告诉别人这个程序是

    用来做什么的,比如刚才的注释,就是说明本程序时要计算那个表达

    式。

    a = 19 + 2 4 – 8 2

    所谓语句,就是告诉程序要做什么事情。程序是由各种各样的语句

    组成的。这条语句还有一个名字,叫作赋值语句。19+2482是一个表

    达式,最后要计算出一个结果,这个结果就是一个对象。

    “=”,不要理解为数学中的等号,它的作用不是“等于”,而是完成

    赋值语句中“赋值”的功能。a是变量。这样就完成了一个赋值过程。

    语句和表达式的区别:“表达式就是某件事”,“语句是做某件事”。

    print a这还是一个语句,称之为print语句,就是要打印出a的值(这种说

    法不是非常严格,但是通常都这么说。严格的说法是打印变量a做对应

    的对象的值。但这种说法啰嗦,就直接说打印a的值)。

    是不是在为看到自己写的第一个程序而欣慰呢?1.5 字符串

    如果要对自然语言分类,则常见的是英语、法语、汉语等,语言学

    专家还会把他们归类为什么语系。我虽然不是语言学专家,但是也做了

    一点自己的思考,虽然尚未得到广大人民群众和研究者的广泛认同,但

    是,我相信那句“真理是掌握在少数人手里的”,至少在这里可以用来给

    自己壮壮胆。

    我对语言的分类方法是:

    类别一:语言中的两个元素(比如两个字)拼接在一起,出来一个

    新的元素(比如把“女”和“子”拼接起来,就是“好”,得到了新的

    字)。

    类别二:两个元素连接在一起(与“拼接”有差别),也就是这两个

    元素并列显示。比如“好”和“人”,两个元素连接在一起是“好人”。

    而3和5拼接(就是整数求和)在一起是8(属于第一类),如果连

    接,就是35,那就属于第二类了。

    上述分类方法也适用于英文,是否适用于其他语种还有待验证。

    把我的这种分法抽象一下(因为有这种简单的抽象,才显示出上述

    语言的分类方法高于一般的语言学专家所认同的方法):

    类别一是:△+□=○

    类别二是:△+□=△□

    根据我个人的研究,在目前知晓的语言范畴中,都没有离开以上两

    种分类,不是第一类就是第二类。

    1.5.1 字符串

    在我洋洋自得的时候,我搜索了一下,才发现自己没那么高明,维基百科的“字符串”词条是这么说的:

    字符串(String),是由零个或多个字符组成的有限串行。一般记

    为s=a[1]a[2]...a[n]。

    看到维基百科的伟大了吧,它已经把我所设想的那种情况取了一个

    形象的名称,叫作字符串,其本质上就是一串字符。

    根据这个定义,前面两次让一个程序员感到伟大的“Hello,World”就是一个字符串。或者说不管是用英文还是中文还是别的某种

    文,写出来的文字都可以作为字符串对待,当然,里面的特殊符号,也

    可以作为字符串,比如空格等。

    在Python中,“万物皆对象”,显然“Hello,World”就是一个对象,这个对象是一个字符串,也就是说,字符串是对象类型,用str表示,这

    就如同前面遇到的int类型一样。字符串类型的对象通常用单引号或者双

    引号包裹起来。

    >>> I love Python.

    'I love Python.'

    >>> 'I LOVE PYTHON.'

    'I LOVE PYTHON.'

    从这两个例子中可以看出,不论是使用单引号还是双引号,结果都

    是一样的。

    >>> 250

    250

    >>> type(250)

    

    >>> 250

    '250'

    >>> type(250)

    

    在这个例子中同样是250,但区别很大。一个没有放在引号里面,一个放在了引号里面,用type函数来检验一下,发现它们居然是两种

    不同的对象类型,前者是int类型,后者则是str类型,即字符串类型。所

    以,请大家务必注意,不是所有数字都是int(或者float)类型,如果它

    在引号里面,就是字符串了。如果搞不清楚是什么类型的话,就让

    type来帮忙搞定。操练起来:

    >>> print good good study, day day up

    good good study, day day up

    >>> print ----good---study---day----up----good---study---day----up

    在print后面打印的都是字符串。注意,引号不是字符串的组成部

    分,而是在告诉计算机里面包裹着的是一个字符串。如果使用Python

    3.x,应该使用print函数,在Python 3.x中,类似的效果由print函数完

    成。

    爱思考的读者肯定想到一个问题,如果要把下面这句话看作一个字

    符串应该怎么做?

    What's your name?

    这句话中有一个单引号,如果在交互模式中像上面那样直接输入,就会这样:

    >>> 'What's your name?'

    File , line 1

    'What's your name?'

    ^

    SyntaxError: invalid syntax

    出现了SyntaxError(语法错误)引导的提示,这是在告诉我们这里

    存在错误,错误的类型就是SyntaxError,后面是对这种错误的解

    释“invalid syntax”(无效的语法)。特别注意,错误提示的上面,有一

    个“^”符号,指着一个单引号,是在告诉我们这里出现错误了。

    在Python中,这一点是非常友好的,如果语句存在错误,就会将错

    误输出来,供程序员参考。当然,有时候错误来源比较复杂,需要根据

    经验和知识进行修改。还有一种修改错误的好办法,就是将错误提示放

    到Google中进行搜索。

    上面那个值的错误原因是什么呢?仔细观察,发现在那句话中事实

    上有三个单引号,本来一对单引号之间包裹的是一个字符串,现在出现

    了三个单引号,Computer姑娘迷茫了,她不知道单引号包裹的到底是

    谁,于是报错。解决方法一:双引号包裹单引号

    >>> What's your name?

    What's your name?

    双引号里面允许出现单引号,反过来,单引号里面也可以包裹双引

    号,这个可以笼统地称为二者的嵌套。

    解决方法二:使用转义符

    所谓转义,就是让某个符号不再表示某种含义,而是表示另外一种

    含义。转义符的作用就是它能够转变符号的含义。在Python中,用“\”(反斜杠)作为转义符(其他很多语言只要有转义符的,都用这个

    符号)。

    >>> 'What\'s your name?'

    What's your name?

    是不是看到转义符的作用了?

    本来单引号不是字符串的一部分,但是如果前面有转义符,那么它

    就失去了原来的含义,转化为字符串的一部分,相当于一个特殊字符

    了。

    关于转义符的问题后面还会遇到,性子急的读者可以向后翻阅或者

    自己搜索一下。

    1.5.2 变量和字符串

    大家对于“变量”已经不陌生了吧,这里是第二次出现了,“一回生

    二回熟”。一条金科玉律是:在Python中“变量无类型,对象有类型”。变

    量相当于一个标签,贴在了不同的对象上。这种“贴”的动作,可以通过

    复制语句完成。

    同样,对字符串类型的对象也是这样,能够通过赋值语句,将对象

    与某个标签(变量)关联起来。>>> b = hello,world

    >>> b

    'hello,world'

    >>> print b

    hello,world

    依然请出type函数,得到变量类型:

    >>> type(b)

    

    1.5.3 连接字符串

    把两个数字用“+”符号连接起来,比如3+5,结果为8,这其实是求

    和。但是,对字符串进行类似操作呢?是这样的:

    >>> py + thon

    'python'

    两个字符串“相加”,就相当于把两个字符串连接起来。别的运算就

    别尝试了,没什么意义,肯定报错,不信就试试:

    >>>py-thon 我这么做,是不是脑袋进水泥了?

    Traceback (most recent call last):

    File , line 1, in

    TypeError: unsupported operand type(s) for -: 'str' and 'str'

    用“+”号实现连接的确比较简单,不过,有时候你会遇到这样的问

    题:

    >>> a = 1989

    >>> b = free

    >>> print b + a

    Traceback (most recent call last):

    File , line 1, in

    TypeError: cannot concatenate 'str' and 'int' objects

    报错了,其错误原因已经打印出来了(一定要注意看打印出来的信

    息,这是解决问题的入口):cannot concatenate'str'and'int'objects。原来a

    对应的对象是一个int类型的,不能将它和str类型的对象连接起来。怎么

    办?用“+”拼接起来的两个对象必须是同一种类型的。如果两个都是数

    字,毫无疑问是正确的,就是求和;如果都是字符串,那么就得到一个

    新的字符串。

    修改上面的错误,可以通过以下方法:

    >>> print b + `a`

    free1989

    你是不是照着上面敲过代码呢?你的结果有没有报错?

    注意:``是反引号,不是单引号,就是键盘中通常在数字1左边的那

    个键,在英文半角状态下输入的符号。这种方法,在编程实践中较少应

    用,特别是在Python 3中,已经把这种方式弃绝了。我想原因就是这个

    符号太容易和单引号混淆了,且在编程中也不容易看出来,可读性太

    差。

    常言道:“困难只有一个,但解决困难的方法不止一种”,既然反引

    号的可读性不好,在编程实践中就尽量不要使用。于是乎就有了下面的

    方法,这是被广泛采用的。不仅简单,更主要的是直白,让人一看就

    懂。

    >>> print b + str(a)

    free1989

    用str(a)实现将整数对象转换为字符串对象。虽然str是一种对象

    类型,但是它也能够实现对象类型的转换,这就起到了一个函数的作

    用。其实前面已经讲过的int也有类似的作用,比如:

    >>> a = 250

    >>> type(a)

    

    >>> b = int(a)

    >>> b

    250

    >>> type(b)

    

    如果你对int和str比较好奇,可以在交互模式中使用help(int),学

    习help(str)可以查阅相关的其他资料。

    看本书的时候,一定要同时打开计算机,一边看一边操作才不睡觉,尽管本书充满了“水分”,让你难以入睡,但是这种不是小说的书

    籍,总是在催眠上有很好疗效的。

    还有第三种:

    >>> print b + repr(a) repr(a)与上面的类似

    free1989

    这里repr是一个函数,其实就是反引号的替代品,它能够把结果

    字符串转化为合法的Python表达式。

    可能读者这时候心存疑惑,它们三者之间有区别吗?首先明确,repr和``是一致的,就不用区别了。接下来需要区别的就是repr和

    str,一个最简单的区别:repr是函数,str跟int一样是一种对象类型。不

    过,仅这么说是不能完全解惑的,幸亏有Google让我辈使用,你会找到

    很多人对这两者进行区分的内容,我推荐以下这些:

    1.When should i use strand when should i use repr?

    Almost always use str when creating output for end users.

    repr is mainly useful for debugging and exploring.For example,if you

    suspect a string has non printing characters in it,or a float has a small

    rounding error,repr will show you;str may not.

    repr can also be useful for for generating literals to paste into your

    source code.It can also be used for persistence(with ast.literal_eval or

    eval),but this is rarely a good idea--if you want editable persisted

    values,something like JSON or YAML is much better,and if you don't

    plan to edit them,use pickle.

    2.In which cases i can use either of them?

    Well,you can use them almost anywhere.You shouldn't generally use

    them except as described above.

    3.What can strdo which reprcan't?

    Give you output fit for end-user consumption--not always(e.g.,str(['spam','eggs'])isn't likely to be anything you want to put in a

    GUI),but more often than repr.

    4.What can reprdo which strcan't

    Give you output that's useful for debugging--again,not always(the

    default for instances of user-created classes is rarely helpful),but

    whenever possible.

    And sometimes give you output that's a valid Python literal or other

    expression--but you rarely want to rely on that except for interactive

    exploration.

    以上英文内容来源:

    http:stackoverflow.comquestions19331404str-vs-repr-functions-in-

    python-2-7-5。

    1.5.4 转义字符

    在字符串中,有时需要输入一些特殊的符号,但是,某些符号不能

    直接输出,就需要用转义符。所谓转义,就是不采用符号本来的含义,而采用另外一种含义。下面列出常用的转义符,如表1-2所示。

    表1-2 常用的转义符以上所有转义符,都可以通过交互模式下print来测试一下,感受实

    际上是什么样子的。例如:

    >>> print hello.I am qiwsir.\ 这里换行,下一行接续... My website is 'http:qiwsir.github.io'.

    hello.I am qiwsir.My website is 'http:qiwsir.github.io'.

    >>> print you can connect me by qq\\weibo\\gmail \\是为了要后面那个 you can connect me by qq\weibo\gmail

    总要自己多练习,才能充分理解转义符的作用。

    1.5.5 原始字符串

    用转义符能够让字符串中的某些符号表示原来的含义,而不是被解

    析成某种具有特别能力的符号。为了说话简单,我们常常把那种每个字

    符都是原始含义的字符串说成原始字符串,比如反斜杠,其不会被看作

    转义符,就是一个反斜杠。

    >>> print I like \npython

    I like

    python

    这里的反斜杠就不是“反斜杠”的原始符号含义,而是和后面的n一起表示换行(转义了)。当然,这似乎没有什么太大影响,但有时候可

    能会出现问题,比如打印DOS路径。

    >>> dos = c:\news

    >>> dos

    'c:\news' 这里貌似没有什么问题

    >>> print dos 当用print来打印这个字符串的时候就出问题了。

    c:

    ews

    如何避免?用前面讲过的转义符可以解决,读者试一下。

    我当然就不能再用转义符了,要不然就真的“太水”了。我用下面的

    方法:

    >>> dos = rc:\news

    >>> print dos

    c:\news

    >>> print rc:\news\python

    c:\news\python

    状如rc:\news,由r开头引起的字符串就是声明了后面引号里的东

    西是原始字符串,在里面放任何字符都表示该字符的原始含义。

    这种方法在做网站设置和网站目录结构的时候非常有用,使用了原

    始字符串就不需要转义了。

    1.5.6 raw_input和print

    小孩学说话是一个模仿的过程,周围的人说什么,孩子就重复什

    么。如果你已经忘记自己当初是怎么学说话的了,那么就找个小孩子观

    察一下吧,最好是观察自己的孩子,如果没有,就要抓紧了。

    我想用Python实现类似的功能。

    在写这个功能前,要了解两个函数:raw_input(如果是使用Python

    3.x,请转换为input)和print。

    这两个都是Python的内建函数(built-in function)。关于Python的内

    建函数,下面都列出来了,供参考。abs、divmod、input、open、staticmethod、all、enumerate、int、ord、str、any、eval、isinstance、pow、sum、basestring、execfile、issubclass、print、super、bin、file、iter、property、tuple、bool、filter、len、range、type、bytearray、float、list、raw_input、unichr、callable、format、locals、reduce、unicode、chr、frozenset、long、reload、vars、classmethod、getattr、map、repr、xrange、cmp、globals、max、reversed、zip、compile、hasattr、memoryview、round、import、complex、hash、min、set、apply、delattr、help、next、setattr、buffer、dict、hex、object、slice、coerce、dir、id、oct、sorted、intern。

    这些内建函数,怎么才能知道哪个函数怎么用,且是干什么用的

    呢?

    曾记否?前面使用过的方法在这里再演示一遍,这种方法是学习

    Python的法宝。

    >>> help(raw_input)

    然后就出现:

    Help on built-in function raw_input in module __builtin__:

    raw_input(...)

    raw_input([prompt]) -> string

    Read a string from standard input. The trailing newline is stripped.

    If the user hits EOF (Unix: Ctl-D, Windows: Ctl-Z+Return), raise EOFError.

    On Unix, GNU readline is used if enabled. The prompt string, if given,is printed without a trailing newline before reading.

    是不是已经清晰地看到了raw_input的使用方法了?

    还有第二种方法,那就是到Python的官方网站,查看内建函数的说

    明,网址:https:docs.python.org2libraryfunctions.html。

    其实,上面列出内建函数名称,就是在这个网页中抄过来的。如果

    读者愿意跨越发展,就应当用上面的方法把每个内建函数怎么使用、返

    回值是什么等都查看一遍,做到心中有数。

    进入交互模式,操练一番:>>> raw_input(input your name:)

    input your name:python

    'python'

    输入名字之后,就返回了输入的内容,用一个变量可以获得这个返

    回值。

    >>> name = raw_input(input your name:)

    input your name:python

    >>> name

    'python'

    >>> type(name)

    

    而且,返回的结果是str类型。如果输入的是数字呢?

    >>> age = raw_input(How old are you?)

    How old are you?10

    >>> age

    '10'

    >>> type(age)

    

    返回的结果仍然是str类型。

    再试试print(若不晓得怎么用,可以用help去看看)。

    >>> print hello, world

    hello, world

    >>> a = python

    >>> b = good

    >>> print a

    python

    >>> print a,b

    python good

    比较简单吧。

    要特别提醒的是,print的返回值默认是以\n结尾的,所以,每个输

    出语句之后自动换行。

    有了以上两个准备,接下来就可以写一个能够“对话”的小程序了。

    !usrbinenv python

    coding=utf-8

    name = raw_input(What is your name?)age = raw_input(How old are you?)

    print Your name is:, name

    print You are + age + years old.

    after_ten = int(age) + 10

    print You will be + str(after_ten) + years old after ten years.

    对这段小程序有一些说明。

    前面演示了print的使用,除了打印一个字符串之外,还可以打印字

    符串拼接结果。

    print You are + age + years old.

    注意,变量age必须是字符串,如最后的那个语句中:

    print You will be + str(after_ten) + years old after ten years.

    这句话里面有一个类型转化,将原本是整数型after_ten转化为了str

    类型,否则就会报错。

    同样注意,在after_ten=int(age)+10中,通过raw_input得到的是str

    类型,当age和10求和的时候,需要先用int函数进行类型转化,才能和

    后面的整数10相加。

    这个小程序基本上把已经学到的东西综合运用了一次。请读者自行

    调试一下,如果没有通过,则仔细看报错信息,你能够从中获得修改方

    向的信息。

    1.5.7 索引和切片

    字符串是一个话题中心,在某些朋友的程序员生涯中,处理字符串

    的机会可能远远高于处理数字的机会。这可能是因为现在的“程序”越来

    越多地处理人类的交往信息,所以高级编程语言也越来越多地处理字符

    串了。

    想想字符串的定义,再看看这样一个字符串“python”,还记得前面

    对字符串的定义吗?它就是几个字符(p、y、t、h、o、n)排列起来。这种排列是非常严格的,不仅仅是字符本身,而且还有顺序,换言之,如果某个字符换了,就变成一个新字符串了;如果这些字符顺序发生了

    变化,则也将成为一个新字符串。

    在Python中,把像字符串这样的对象类型(后面还会冒出来类似的

    其他有这种特点的对象类型,比如列表)统称为序列。顾名思义,序列

    就是“有序排列”。

    水泊梁山的108个好汉(里面分明也有女的,难道女汉子是从这里

    来的吗?),就是一个“有序排列”的序列。从老大宋江一直排到第108

    位金毛犬段景住。在这个序列中,每个人有编号,编号和每个人一一对

    应:1号是宋江,2号是卢俊义。反过来,通过每个人的姓名,也能找出

    其对应的编号:武松是多少号?14号。李逵呢?22号。

    在Python中,给这些编号取了一个文雅的名字,叫作索引(别的编

    程语言也这么称呼,不是Python独有的)。

    >>> lang = study python

    >>> lang[0]

    's'

    >>> lang[1]

    't'

    变量lang是贴在字符串“study python”上的标签,如果要得到这个字

    符串的第一个单词s,可以用lang[0]。

    当然,如果你不愿意通过赋值语句让变量lang指向那个字符串,也

    可以这样做:

    >>> study python[0]

    's'

    效果是一样的,但是方便程度显而易见。

    字符串这个序列的排序方法跟梁山好汉有点不同:第一个不是用数

    字1表示,而是用数字0表示,其他很多语言也都是从0开始排序的。为

    什么这样做呢?这就是规定。当然,这个规定是有一定优势的,此处不

    展开,有兴趣的读者可以去网上搜索一下,有专门对此进行解释的文

    章。如表所示,将这个字符串从第一个到最后一个进行了排序,特别注

    意,两个单词中间的那个空格,也占用了一个位置。

    通过索引能够找到该索引所对应的字符,那么反过来,能不能通过

    字符找到其在字符串中的索引值呢?怎么找?

    >>> lang.index(p)

    6

    这样是不是已经能够和梁山好汉的例子对上号了?只不过区别在于

    程序的第一个索引值是0。

    如果某一天,宋江大哥站在大石头上,向各位弟兄大喊:“兄弟

    们,都排好队。”等兄弟们排好之后,宋江说:“现在给各位没有老婆的

    兄弟分配女朋友,我这里已经有了名单,我念到的兄弟站出来,不过我

    是按照序号来念的。第29号到第34号先出列,到旁边房子等候分配女朋

    友。”

    在前面的例子中lang[1]能够得到原来字符串的第二个字符t,就相当

    于从原来字符串中把这个“切”出来了。不过,我们这么“切”却不影响原

    来字符串的完整性,当然也可以理解为将字符t复制一份拿出来了。

    类似宋江大哥那样,一次性将几个兄弟一起叫出来,Python也能做

    到。

    >>> lang

    'study python' 在前面“切”了若干的字符之后,再看一下该字符串,还是完整的。

    >>> lang[2:9]

    'udy pyt'

    通过lang[2:9]要得到多个(不是一个)字符(来源于原字符串),从返回的结果中可以看出,我们得到的是序号分别对应着2、3、4、5、6、7、8(跟上面的表格对应一下)的字符(包括那个空格)。

    不管是得到一个字符还是多个字符,通过索引得到字符的过程都称

    之为切片。切片是一个很有意思的东西,可以“切”出不少花样呢。

    >>> lang

    'study python'

    >>> b = lang[1:] 得到从1号到最末尾的字符,这时最后那个不用写

    >>> b

    'tudy python'

    >>> c = lang[:] 得到所有字符

    >>> c

    'study python'

    >>> d = lang[:10] 得到从第一个到10号之前的字符

    >>> d

    'study pyth'

    在获取切片的时候,如果冒号的前面或者后面的序号不写,则表示

    两边的某个终点位置,或是开头,或是结尾。也就是,lang[:10]的效果

    和lang[0:10]是一样的。

    >>> e = lang[0:10]

    >>> e

    'study pyth'

    那么,lang[1:]和lang[1:11]效果一样吗?请思考后作答。

    >>> lang[1:11]

    'tudy pytho'

    >>> lang[1:]

    'tudy python'

    答案是:不一样,你思考对了吗?

    在“切”字符的时候,如果冒号后面有数字,所得到的切片不包含该

    数字所对应的字符(前包括,后不包括)。那么,是不是可以这样呢?

    lang[1:12]不包括12号(事实上没有12号),是不是可以得到1号到11号

    对应的字符呢?

    >>> lang[1:12]

    'tudy python'

    >>> lang[1:13]

    'tudy python'

    果然结果和猜测的一样,即如果第二个数字大于字符串的长度,得

    到的返回结果就自动到最大长度位置终止。但是请注意,这种获得切片

    的做法在编程实践中是不提倡的。特别是如果后面要用到循环的时候,这样做很可能会遇到麻烦。如果在“切片”的时候,冒号左右都不写数字,就是前面所操作的

    c=lang[:],其结果是变量c的值与原字符串一样,即“复制”了一份。注

    意,这里的“复制”打上了引号,意思是如同复制,是不是真的复制呢?

    可以用下面的方式检验一下:

    >>> id(c)

    3071934536L

    >>> id(lang)

    3071934536L

    id的作用还记得吗?

    从上面可以看出,两个内存地址一样,说明c和lang两个变量指向的

    是同一个对象。用c=lang[:]的方式并没有生成一个新的字符串,而是将

    变量c这个标签也贴在了原来那个字符串上了。

    >>> lang = study python

    >>> c = lang

    如果这样操作,变量c和lang是不是指向同一个对象呢?读者可以自

    行检验。

    1.5.8 基本操作

    所有序列都有如下基本操作,字符串是序列的子集。

    len:返回序列长度。

    +:连接两个序列。

    :重复序列元素。

    in:判断元素是否存在于序列中。

    max:返回最大值。

    min:返回最小值。

    cmp(str1,str2):比较两个序列值是否相同。

    通过下面的例子,将这几个基本操作在字符串上的使用演示一下。

    1)“+”连接字符串>>> str1 = 'abcd'

    >>> str2 = 'abcde'

    >>> str1 + str2

    'abcdabcde'

    >>> str1 + --> + str2

    'abcd-->abcde'

    不要小看“+”号,到此只是学了字符串这一种序列,后面还会遇到

    列表、元组两种序列,都能够如此实现拼接。

    2)in

    >>> a in str1

    True

    >>> de in str1

    False

    >>> de in str2

    in用来判断某个字符串是不是在另外一个字符串内,或者判断某个

    字符串内是否包含某个字符串,如果包含,就返回True,否则返回

    False。

    3)最值

    >>> max(str1)

    'd'

    >>> max(str2)

    'e'

    >>> min(str1)

    'a'

    在一个字符串中,每个字符在计算机内都是有编码的,也就是对应

    着一个数字,min和max就是根据这些数字获得最小值和最大值,然

    后对应出相应的字符。关于这种编号是多少,可以搜索有关字符编码或

    者ASCII编码,很容易查到。

    4)比较

    >>> cmp(str1, str2)

    -1

    将两个字符串进行比较,首先将字符串中的符号转化为对应的数字

    (怎么对应数字了?请参照ASCII理解),然后再比较。如果返回的数

    值小于零,说明第一个小于第二个;等于0,则两个数值相等;大于0,则第一个数值大于第二个数值。为了能够明白其所以然,进入下面的分

    析。

    >>> ord('a')

    97

    >>> ord('b')

    98

    >>> ord(' ')

    32

    ord是一个内建函数,能够返回某个字符(注意,是一个字符,而

    不是多个字符组成的串)所对应的ASCII值(是十进制的),字符a在

    ASCII中的值是97,空格在ASCII中也有值,是32。反过来,根据整数

    值得到相应字符,可以使用chr:

    >>> chr(97)

    'a'

    >>> chr(98)

    'b'

    于是,得到如下比较结果:

    >>> cmp(a, b) a-->97,b-->98,97小于98,所以a小于b。

    -1

    >>> cmp(abc, aaa)

    1

    >>> cmp(a, a)

    0

    看看下面的比较是怎么进行的呢?

    >>> cmp(ad, c)

    -1

    在字符串的比较中,两个字符串的第一个字符先比较,如果相等,就比较下一个,如果不相等,就返回结果。如果直到最后还相等,就返

    回0。位数不够时,按照“没有”处理(注意,“没有”不是0,0在ASCII中

    对应的是NUL),位数多的那个大。ad中的a先和后面的c进行比较,显

    然a小于c,于是返回结果-1。但进行下面的比较,是最容易让人迷茫

    的。读者能不能根据刚才阐述的比较原理理解得到的结果呢?

    >>> cmp(123, 23)

    -1

    >>> cmp(123,23) 也可以比较整数,这时候就是整数的直接比较了。

    15)“”

    字符串中的“乘法”含义是重复那个字符串,在某些时候很好用的,比如要打印一个华丽的分割线:

    >>> str1 3

    'abcdabcdabcd'

    >>> print - 20 不用输入很多个`-`--------------------

    6)len

    要知道一个字符串有多少个字符,一种方法是从头开始盯着屏幕

    数。哦,这不是计算机在干活,是“键客”在干活。

    键客,不是剑客。剑客是以剑为武器的侠客;而键客是以键盘为武

    器的侠客。

    计算机这样来数字符串长度:

    >>> a=hello

    >>> len(a)

    5

    函数len返回该字符串长度。

    >>> m = len(a) 把结果返回后赋值给一个变量

    >>> m

    5

    >>> type(m) 这个返回值(变量)是一个整数型

    

    1.5.9 常用的字符串方法

    字符串的方法有很多,可以通过dir来查看:

    >>> dir(str)

    ['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']这么多字符串方法当然不用都介绍,因为有一种方法,读者可以随

    用随查阅每个字符串方法是如何使用的。

    >>> help(str.isalpha)

    Help on method_descriptor:

    isalpha(...)

    S.isalpha -> bool

    Return True if all characters in S are alphabetic

    and there is at least one character in S, False otherwise.

    按照这里的说明,在交互模式下进行实验。

    >>> python.isalpha 字符串全是字母,应该返回True

    True

    >>> 2python.isalpha 字符串含非字母,返回False

    False

    以下仅列举几个常用的方法。

    1)split

    其作用是将字符串根据某个分割符进行分割。

    >>> a = I LOVE PYTHON

    >>> a.split( )

    ['I', 'LOVE', 'PYTHON']

    这里用空格作为分割,得到一个名字叫作列表(list)的返回值,关于列表的内容,后续会介绍。还能用别的分隔吗?

    >>> b = www.itdiffer.com

    >>> b.split(.)

    ['www', 'itdiffer', 'com']

    2)去掉字符串两头的空格

    比如让用户输入一些信息,有的用户有时候会在信息(比如,自己

    的名字就是字符串)前面或者后面加空格。这些空格是没用的,在使用

    所输入的信息时,必须要把这些空格去掉。

    Python中去掉空格的方法有如下几种:

    S.strip:去掉字符串的左右空格

    S.lstrip:去掉字符串的左边空格S.rstrip:去掉字符串的右边空格

    例如:

    >>> b= hello 两边有空格

    >>> b.strip

    'hello'

    >>> b

    ' hello '

    特别注意,原来的值没有变化,而是新返回了一个结果。

    >>> b.lstrip 去掉左边的空格

    'hello '

    >>> b.rstrip 去掉右边的空格

    ' hello'

    3)字符大小写的转换

    英文有时候要用到大小写转换。最有名的是驼峰命名,里面就有一

    些大写和小写。如果有兴趣,可以来这里学习自动将字符串转化为驼峰

    命名形式的方法(参见:

    https:github.comqiwsiralgorithmblobmasterstring_to_hump.md)。相

    关的方法有:

    S.upper

    S.lower

    S.capitalize

    S.isupper

    S.islower

    S.istitle

    看例子:

    >>> a = qiwsir,python

    >>> a.upper 将小写字母完全变成大写字母

    'QIWSIR,PYTHON'

    >>> a 原数据对象并没有改变

    'qiwsir,python'

    >>> b = a.upper

    >>> b

    'QIWSIR,PYTHON'

    >>> c = b.lower 将所有的大写字母变成小写字母

    >>> c

    'qiwsir,python'>>> a

    'qiwsir,python'

    >>> a.capitalize 把字符串的第一个字母变成大写

    'Qiwsir,python'

    >>> a 原数据对象没有改变

    'qiwsir,python'

    >>> b = a.capitalize

    >>> b

    'Qiwsir,python'

    >>> a = qiwsir,github

    >>> a.istitle

    False

    >>> a = QIWSIR 当全是大写的时候,返回False

    >>> a.istitle

    False

    >>> a = qIWSIR

    >>> a.istitle

    False

    >>> a = Qiwsir,github 如果这样,也返回False

    >>> a.istitle

    False

    >>> a = Qiwsir 这样是True

    >>> a.istitle

    True

    >>> a = 'Qiwsir,Github' 这样也是True

    >>> a.istitle

    True

    >>> a = Qiwsir

    >>> a.isupper

    False

    >>> a.upper.isupper

    True

    >>> a.islower

    False

    >>> a.lower.islower

    True

    >>> a = This is a Book

    >>> a.istitle

    False

    >>> b = a.title 这样就把所有单词的第一个字母转化为大写

    >>> b

    'This Is A Book'

    >>> b.istitle 判断每个单词的第一个字母是否为大写

    4)join连接字符串

    用“+”能够连接字符串,但不是什么情况下都能够如愿。比如,将

    列表(列表是另外一种类型)中的每个字符(串)元素拼接成一个字符

    串,并且用某个符号连接,但如果用“+”会比较麻烦。用字符串的join方

    法就比较容易实现。

    >>> b

    'www.itdiffer.com'>>> c = b.split(.)

    >>> c

    ['www', 'itdiffer', 'com']

    >>> ..join(c)

    'www.itdiffer.com'

    >>> .join(c)

    'wwwitdiffercom'

    1.5.10 字符串格式化输出

    什么是格式化?在维基百科中有专门的词条,是这么说的:

    格式化是指对磁盘或磁盘中的分区(Partition)进行初始化的一种

    操作,这种操作通常会导致现有的磁盘或分区中所有的文件被清除。

    不知道你是否知道这种“格式化”。显然,此格式化非我们这里所说

    的,我们说的是字符串的格式化,或者说是“格式化字符串”,表示的意

    思就是:

    格式化字符串,是C、C++等程序设计语言printf类函数中用于指定

    输出参数的格式与相对位置的字符串参数。其中的转换说明

    (conversion specification)用于把随后对应的0个或多个函数参数转换

    为相应的格式输出;格式化字符串中转换说明以外的其他字符原样输

    出。

    这也是来自维基百科的定义。在这个定义中,用C语言作为例子,并且用了其输出函数来说明。在Python中,也有同样的操作和类似的函

    数print,此前我们已经了解一二了。

    将那个定义说得通俗一些:字符串格式化就是要先制定一个模板,在这个模板中某个或者某几个地方留出空位来,然后在那些空位填上字

    符串。那么,那些空位需要用一个符号来表示,这个符号通常被叫作占

    位符(仅仅是占据着那个位置,并不是输出的内容)。

    >>> I like %s

    'I like %s'

    在这个字符串中,有一个符号“%s”,这是一个占位符,可以被其他

    的字符串代替。比如:>>> I like %s % python

    'I like python'

    >>> I like %s % Pascal

    'I like Pascal'

    这是较为常用的一种字符串输出方式。

    不同的占位符,表示那个位置应该被不同类型的对象填充,如表1-

    3所示。常用的只有%s、%d和%f,如果需要其他的,到这里来查即

    可。

    看例子:

    >>> a = %d years % 15

    >>> print a

    15 years

    表1-3 占位符

    当然,还可以在一个字符串中设置多个占位符,就像下面一样:

    >>> print Suzhou is more than %d years. %s lives in here. % (2500, qiwsir)

    Suzhou is more than 2500 years. qiwsir lives in here.

    对于浮点数字的打印输出,还可以限定输出的小数位数和其他样

    式:

    >>> print Today's temperature is %.2f % 12.235

    Today's temperature is 12.23

    >>> print Today's temperature is %+.2f % 12.235

    Today's temperature is +12.23

    注意:在上面的例子中,没有实现四舍五入的操作,只是截取,但

    是上面的例子也的确太特殊了。如果读者有兴趣,可以换一个数,自己试试,在一般情况下是能够实现四舍五入的。

    关于类似的操作还有很多变化,比如输出格式的宽度是多少等。如

    果读者在编程中遇到了,可以到网上查找。在这里给一个参考图示,也

    是从网上下载的,如图1-6所示。

    图1-6 字符串格式

    其实,上面这种格式化方法,常常被认为太“古老”了。因为在

    Python中还有新的格式化方法。

    >>> s1 = I like {}.format(python)

    >>> s1

    'I like python'

    >>> s2 = Suzhou is more than {0} years. {1} lives in here..format(2500, qiwsir)

    >>> s2

    'Suzhou is more than 2500 years. qiwsir lives in here.'

    这就是Python非常提倡的string.format的格式化方法,其中{}作为

    占位符。

    这种方法真得非常好,而且非常简单,只需要将对应的东西按照顺

    序在format后面的括号中排列好,分别对应占位符{}即可。如果你觉得还不明确,还可以这样来做。

    >>> print Suzhou is more than {year} years. {name} lives in here..format(year=2500, name=qiwsir)

    Suzhou is more than 2500 years. qiwsir lives in here.

    真的很简洁、优雅。

    还有一种格式化的方法是“字典格式化”,这里仅仅举一个例子,如

    果读者要了解“字典”的含义,本教程后续会有的。

    >>> lang = python

    >>> print I love %(program)s % {program:lang}

    I love python

    这里列举了三种基本格式化的方法,你喜欢那种?我推荐:

    string.format。1.6 字符编码

    在Python 2.x中,字符编码是一个让人困惑的问题,这个问题在

    Python 3.x中自然解决了。由此可以说,未来是Python 3的。但是,由于

    前面已经分析过的原因,在一段时间内Python 2.x还不能完全丢弃,甚

    至不少工程项目还是以它为主。所以,还要将字符编码问题单独叙述。

    如果一个字符串都是英文,就没有所谓编码问题。但在我们的环境

    中,中文是我们不得不用的。

    >>> name = '老齐'

    >>> name

    '\xe8\x80\x81\xe9\xbd\x90'

    你在交互模式中遇到过上面的情形吗?这就是显示汉字的问题,英

    文就不这样了。

    难道这是中文的错吗?看来投胎真的是一个技术活。是的,投胎是

    技术活,但上面的问题不是中文的错。

    1.6.1 编码

    什么是编码?这是一个比较玄乎的问题,也不好下一个普通定义。

    我看到有的教材中有定义,且不敢说其定义不对,但至少是不容易理

    解。

    “古代打仗,击鼓进攻、鸣金收兵”这就是编码。把要传达给士兵的

    命令对应为一定的其他形式,比如命令“进攻”,经过信息传递,如图1-

    7所示。图1-7 信息传递

    1)长官下达进攻命令,传令员将这个命令编码为鼓声。

    2)鼓声在空气中传播,比传令员的嗓子吼出来的声音传播得更

    远,士兵听到后也不会有歧义,这就是“进攻”命令被编码成鼓声之后的

    优势所在。

    3)士兵听到鼓声,就是接收到信息,如果接受过训练或者有人告

    诉过他们,他们就知道这是命令进攻,这个过程就是解码。所以,编码

    方案要有两套:一套在信息发出者那里,另外一套在信息接受者这里。

    经过解码之后,士兵明白了才行动。

    以上过程比较简单,但真实的编码和解码过程比这个复杂。不过,原理都差不多。

    举一个似乎遥远,其实不久前人们都在使用的东西做例子:电报

    (以下引用的内容来自《维基百科》)。电报是通信业务的一种,在19世纪初发明,是最早使用电进行通信

    的方法。电报大为加快了消息的流通,是工业社会的一项重要发明。早

    期的电报只能在陆地上通信,后来使用了海底电缆,开展了越洋服务。

    到了20世纪初,开始使用无线电波发电报,电报业务基本上已能抵达地

    球上大部分地区。电报主要用作传递文字讯息,使用电报技术用作传送

    图片称为传真。

    中国出现首条电报线路是1871年,由英国、俄国及丹麦敷设,从中

    国香港经上海至日本长崎,且是海底电缆。由于清政府的反对,电缆被

    禁止在上海登录。后来丹麦公司不理清政府的禁令,将线路引至上海公

    共租界,并在1871年6月3日起开始收发电报。至于中国首条自主敷设的

    线路,是由福建巡抚丁日昌在中国台湾所建,1877年10月完工,连接台

    南及高雄。1879年,北洋大臣李鸿章在天津、大沽及北塘之间架设电报

    线路,用作军事通信。1880年,李鸿章奏准开办电报总局,由盛宣怀任

    总办。并在1881年12月开通天津至上海的电报服务。李鸿章説:“五年

    来,我国创设沿江沿海各省电线,总计一万多里,国家所费无多,巨款

    来自民间。当时正值法人挑衅,将帅报告军情,朝廷传达指示,均相机

    而动,无丝毫阻碍。中国自古用兵,从未如此神速。出使大臣往来问

    答,朝发夕至,相隔万里好似同居庭院。举设电报一举三得,既防止外

    敌侵略,又加强国防,亦有利于商务。”天津官电局于庚子遭乱全毁。

    1887年,台湾巡抚刘铭传敷设了福州至台湾的海底电缆,是中国首条海

    底电缆。1884年,北京电报开始建设,采用“安设双线,由通州展至京

    城,以一端引入署中,专递官信,以一端择地安置用便商民”,8月5

    日,电报线路开始建设,所有电线杆一律漆成红色。8月22日,位于北

    京崇文门外大街西的喜鹊胡同的外城商用电报局开业。同年8月30日,位于崇文门内泡子和以西的吕公堂开局,专门收发官方电报。

    为了传达汉字,电报部门准备由4位数字或3位罗马字构成的代码,即中文电码,采用发送前将汉字改写成电码发出,收电报后再将电码改

    写成汉字的方法。

    注意:这里出现了电报中用的“中文电码”,这就是一种编码,将汉

    字对应成阿拉伯数字,从而能够用电报发送汉字。

    1873年,法国驻华人员威基杰参照《康熙字典》的部首排列方法,挑选了常用汉字6800多个,编成了第一部汉字电码本《电报新书》。

    电报中的编码被称为摩尔斯电码,英文是Morse Code。摩尔斯电码(英语:Morse Code)是一种时通时断的信号代码,通

    过不同的排列顺序来表达不同的英文字母、数字和标点符号。是由美国

    人萨缪尔·摩尔斯在1836年发明。

    摩尔斯电码是一种早期的数字化通信形式,但是它不同于现代只使

    用0和1两种状态的二进制代码,它的代码包括五种:点(.)、划

    (-)、每个字符间短的停顿(在点和划之间的停顿)、每个词之间中

    等的停顿以及句子之间长的停顿。

    看来电报员是一个技术活,不同长短的停顿都代表了不同意思。

    哦,对了,有一个老片子叫《永不消逝的电波》,保证你看完之后才知

    道,里面根本就没有讲电报是怎么编码的。

    摩尔斯电码在海事通信中被作为国际标准一直使用到1999年。1997

    年,当法国海军停止使用摩尔斯电码时,发送的最后一条消息是:“所

    有人注意,这是我们在永远沉寂之前最后的一声呐喊!”

    我瞪着眼看了老长时间,这两行不是一样的吗?

    不管这个了,总之,这就是编码。

    1.6.2 计算机中的字符编码

    抄一段维基百科对字符编码的解释:

    字符编码(英语:Character Encoding),也称为字集码,是把字符

    集中的字符编码为指定集合中某一对象(例如:比特模式、自然数串

    行、8位组或者电脉冲),以便文本在计算机中存储和通过通信网络的

    传递。常见的例子包括将拉丁字母表编码成摩斯电码和ASCII。其中,ASCII将字母、数字和其他符号编号,并用7比特的二进制来表示这个整

    数。通常会额外使用一个扩充的比特,以便于以1个字节的方式存储。在计算机技术发展的早期,如ASCII(1963年)和EBCDIC(1964

    年)这样的字符集逐渐成为标准。但这些字符集的局限很快就变得明

    显,于是人们开发了许多方法来扩展它们。对于支持包括东亚CJK字符

    家族在内的写作系统的要求能支持更大量的字符,并且需要一种系统而

    不是临时的方法实现这些字符的编码。

    在这个世界上,有好多不同的字符编码。但是,它们不是自己随便

    搞搞的,而是要有一定的基础,往往是以名叫ASCII的编码为基础。

    ASCII(American Standard Code for Information Interchange,美国信

    息交换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显

    示现代英语,而其扩展版本EASCII则可以部分支持其他西欧语言,并

    等同于国际标准ISOIEC 646。由于万维网使得ASCII广为通用,直到

    2007年12月,逐渐被Unicode取代。

    上面的引文中已经说了,现在我们用的编码标准已经变成Unicode

    了(Python3.x就是用了Unicode),那么什么是Unicode呢?还是抄一段

    来自维基百科的说明:

    Unicode(中文:万国码、国际码、统一码、单一码)是计算机科

    学领域里的一项业界标准。它对世界上大部分的文字系统进行了整理、编码,使得电脑可以用更为简单的方式来呈现和处理文字。

    Unicode伴随着通用字符集的标准而发展,同时也以书本的形式对

    外发表。Unicode至今仍在不断增修,每个新版本都加入更多新的字

    符。目前最新的版本为7.0.0,已收入超过十万个字符(第十万个字符在

    2005年获采纳)。Unicode涵盖的数据除了视觉上的字形、编码方法、标准的字符编码外,还包含了字符特性,如大小写字母。

    听这名字:万国码,那就一定包含了中文。但是,光有一个

    Unicode还是不够用(可以访问《维基百科》网站查看相关说明),还

    要有其他的一些编码实现方式,Unicode的实现方式称为Unicode转换格

    式(Unicode Transformation Format,简称为UTF),于是乎有了一个我

    们在很多时候都会看到的utf-8。

    什么是utf-8?还是看维基百科上怎么说的吧:

    UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,也是一种前缀码。它可以用来表示Unicode标准

    中的任何字符,且其编码中的第一个字节仍与ASCII兼容,这使得原来

    处理ASCII字符的软件不需要或只做少部份修改,即可继续使用。因

    此,它逐渐成为电子邮件、网页及其他存储或发送文字的应用中优先采

    用的编码。

    是不是理解了呢?前面写程序的时候,曾经出现过coding:utf-8的字

    样,就是在告诉Python我们要用什么字符编码。

    1.6.3 encode和decode

    encode和decode是两个内置函数。

    codecs.encode(obj[,encoding[,errors]]):Encodes obj using the

    codec registered for encoding.

    codecs.decode(obj[,encoding[,errors]]):Decodes obj using the

    codec registered for encoding.

    Python2默认的编码是ASCII,通过encode可以将对象的编码转换

    为指定编码格式(称作“编码”),而decode是这个过程的逆过程(称

    作“解码”)。

    做一个实验,才能理解:

    >>> a = 中

    >>> type(a)

    

    >>> a

    '\xe4\xb8\xad'

    >>> len(a)

    3

    >>> b = a.decode

    >>> b

    u'\u4e2d'

    >>> type(b)

    

    >>> len(b)

    1在做这个实验之前,或许还不是很迷茫(知道得越多越迷茫),实

    验做完了,自己也迷茫了。别急躁,对编码问题的理解要慢慢来,如果

    一时理解不了,就先按照要求做,做着做着就豁然开朗了。

    变量a引用了一个字符串类型对象,但严格地讲是字节串,因为它

    是经过编码后的字节组成的序列。也就是你在上面的实验中看到

    的“中”这个字在计算机中编码之后的字节表示。(关于字节可以搜索一

    下)。用len(a)来度量它的长度,它是由三个字节组成的。

    然后通过decode函数将字节串转变为字符串,并且这个字符串是按

    照Unicode编码的。在Unicode编码中,一个汉字对应一个字符,这时候

    度量它的长度就是1。

    反过来,一个Unicode编码的字符串也可以转换为字节串。

    >>> c = b.encode('utf-8')

    >>> c

    '\xe4\xb8\xad'

    >>> type(c)

    

    >>> c == a

    关于编码问题先到这里点到为止吧。因为再扯,还会扯出问题来,读者肯定感到不满意,因为还没有知其所以然。

    1.6.4 避免中文是乱码

    “避免中文是乱码”是一个具有很强操作性的问题。

    首先,提倡使用utf-8编码方案,因为它跨平台不错。

    经验一,在开头声明:

    -- coding: utf-8 --

    有朋友问我“--”有什么作用,那个就是为了好看,爱美之心人皆

    有,更何况程序员?当然,也可以写成: coding:utf-8

    经验二,遇到字符(节)串,立刻转化为unicode,不要用str,直

    接使用unicode:

    unicode_str = unicode('中文', encoding='utf-8')

    print unicode_str.encode('utf-8')

    经验三,如果对文件操作,打开文件的时候,最好用codecs.open替

    代open(关于文件的操作,请参阅后续内容。)

    import codecs

    codecs.open('filename', encoding='utf8')

    最后,如果用Python3,这种编码的烦恼会少一点。1.7 列表

    此前,已经知道了三种Python的对象类型:int、float和str。

    这一节中的list类型,也是Python的一种对象类型,翻译为:列表。

    下面的加粗字,请读者注意:

    list在Python中具有非常强大的功能。

    1.7.1 定义

    在Python中,用方括号表示一个list:[]

    方括号里面的元素类型,可以是int,也可以是str类型的数据,甚至

    也能够是TrueFalse这种布尔值。看下面的例子,要特别注意阅读注

    释。

    >>> a=[] 定义了一个空的列表,变量a相当于一个贴在其上的标签

    >>> type(a)

     用内置函数type查看变量a引用对象的类型,为list

    >>> bool(a) 用内置函数bool看看a的布尔值,因为是空的,所以为False

    False

    >>> print a 打印

    []

    bool是一个布尔函数,在后续章节会详述。它的作用就是来判断

    一个对象是“真”还是“假”(空)。如果像上面的例子那样,列表中什么

    也没有就是空的,用bool函数来判断,得到False,从而显示它是空

    的。

    不能总玩“空”的,来点“实”的吧。

    >>> a=['2', 3, 'qiwsir.github.io']

    >>> a

    ['2', 3, 'qiwsir.github.io']

    >>> type(a)

    >>> bool(a)

    True

    >>> print a

    ['2', 3, 'qiwsir.github.io']

    一个列表中能够容纳多少东西?“有容乃大”是对列表最好的形容

    了,它的大小仅受制于硬件设备和你的意愿。

    如果你已经了解了别的语言,比如比较常见的Java,里面有一个跟

    list相似的数据类型——数组——但是两者还是有区别的。在Java中,数

    组中的元素必须是基本数据类型中的某一个,也就是要么都是int类型,要么都是char类型等,不能一个数组中既有int类型又有char类型。这是

    因为Java中的数组需要提前声明,声明的时候就确定了里面元素的类

    型。但是尽管Python中的list与Java中的数组有类似的地方——都是[]包

    裹的——list中的元素是任意类型的,可以是int、str,还可以是list,甚

    至是dict等。所以,有一句话说:列表是Python中的苦力,什么都可以

    干。

    1.7.2 索引和切片

    关于索引和切片的含义在字符串章节已经熟知了。所以,这里可以

    很快用起来。

    >>> url = qiwsir.github.io

    >>> url[2]

    'w'

    >>> url[:4]

    'qiws'

    >>> url[3:9]

    'sir.gi'

    在列表中也有类似的操作。只不过是以元素为单位,而不是以字符

    为单位进行索引。

    >>> a

    ['2', 3, 'qiwsir.github.io']

    >>> a[0] 索引序号也是从0开始

    '2'

    >>> a[1]

    3

    >>> a[:2]

    ['2', 3] >>> a[1:]

    [3, 'qiwsir.github.io']

    列表和字符串两种类型都属于序列(都是一些对象按照某个次序排

    列起来,这是序列的最大特征),因此,他们有很多类似的地方。如刚

    才演示的索引和切片是非常一致的。

    >>> lang = python

    >>> lang.index(y)

    1

    >>> lst = ['python','java','c++']

    >>> lst.index('java')

    1

    索引数字从左边开始编号,第一个是0,然后依次增加1。

    此外,还有一种编号方式是从右边开始,右边第一个可以编号

    为-1,然后向左依次是:-2,-3,...,依次类推下来。这对字符串、列

    表等各种序列类型都适用。

    >>> lang

    'python'

    >>> lang[-1]

    'n'

    >>> lst

    ['python', 'java', 'c++']

    >>> lst[-1]

    'c++'

    从右边开始编号,第-1号是右边第一个。但是,如果要切片的话,应该注意:

    >>> lang[-1:-3]

    ''

    >>> lang[-3:-1]

    'ho'

    >>> lst[-3:-1]

    ['python', 'java']

    序列的切片,一定要左边的数字小于右边的数字,lang[-1:-3]就没

    有遵守这个规则,返回的是一个空。

    1.7.3 反转反转在编程中常常会用到。通过举例来说明反转的方法:

    >>> alst = [1,2,3,4,5,6]

    >>> alst[::-1]

    [6, 5, 4, 3, 2, 1]

    >>> alst

    [1, 2, 3, 4, 5, 6]

    当然,对于字符串也可以:

    >>> lang

    'python'

    >>> lang[::-1]

    'nohtyp'

    >>> lang

    'python'

    是否注意到,不管是str还是lst,反转之后原来的值没有改变。这就

    说明,这里的反转,不是在“原地”把原来的值倒过来,而是新生成了一

    个值,生成的值跟原来的值相比,是倒过来了。

    这是一种非常简单的方法,虽然我在写程序的时候常常使用,但并

    不是十分推荐,因为它有时候让人感觉迷茫。Python还有另外一种方法

    让list反转,且比较容易理解和阅读,特别推荐之:

    >>> list(reversed(alst))

    [6, 5, 4, 3, 2, 1]

    这个比较简单,而且很容易看懂,不是吗?

    顺便给出reversed函数的详细说明:

    >>> help(reversed)

    Help on class reversed in module __builtin__:

    class reversed(object)

    | reversed(sequence) -> reverse iterator over values of the sequence

    |

    | Return a reverse iterator

    它返回一个可以迭代的对象(关于迭代的问题,请参阅后续内

    容),不过已经将原来的序列对象反转了。比如:

    >>> list(reversed(abcd))

    ['d', 'c', 'b', 'a']很好、很强大,特别推荐使用。

    1.7.4 对list的操作

    在字符串那部分已经提到过,所有的序列都有几种基本操作。列表

    是一种序列,当然如此。

    1.len

    >>> lst

    ['python', 'java', 'c++']

    >>> len(lst)

    3

    2.+,连接两个序列

    >>> lst

    ['python', 'java', 'c++']

    >>> alst

    [1, 2, 3, 4, 5, 6]

    >>> lst + alst

    ['python', 'java', 'c++', 1, 2, 3, 4, 5, 6]

    3.,重复元素

    >>> lst

    ['python', 'java', 'c++']

    >>> lst 3

    ['python', 'java', 'c++', 'python', 'java', 'c++', 'python', 'java', 'c++']

    4.in

    列表lst还是前面的值:

    >>> python in lst

    True

    >>> c in lst

    False5.max和min

    以int类型元素为例:

    >>> alst

    [1, 2, 3, 4, 5, 6]

    >>> max(alst)

    6

    >>> min(alst)

    1

    >>> max(lst)

    'python'

    >>> min(lst)

    'c++'

    6.cmp

    采用上面的方法,进行比较:

    >>> lsta = [2,3]

    >>> lstb = [2,4]

    >>> cmp(lsta,lstb)

    -1

    >>> lstc = [2]

    >>> cmp(lsta,lstc)

    1

    >>> lstd = ['2','3']

    >>> cmp(lsta,lstd)

    -1

    7.追加元素

    >>> a = [good,python,I]

    >>> a

    ['good', 'python', 'I']

    >>> a.append(like) 向list中添加str类型like

    >>> a

    ['good', 'python', 'I', 'like']

    >>> a.append(100) 向list中添加int类型100

    >>> a

    ['good', 'python', 'I', 'like', 100]

    官方文档这样描述list.append方法:

    list.append(x)

    Add an item to the end of the list; equivalent to a[len(a):] = [x].是否已经理解了list.append(x)的含义呢?即将新的元素x追加到

    list的尾部。

    如果注意看上面官方文档中的那句话,应该注意到后面半句:

    equivalent to a[len(a):]=[x],意思是说list.append(x)等效于

    a[len(a):]=[x]。这也相当于告诉我们另外一种追加元素的方法,并且

    两种方法等效。

    >>> a

    ['good', 'python', 'I', 'like', 100]

    >>> a[len(a):]=[3] len(a),即得到list的长度,这个长度是指list中的元素个数。

    >>> a

    ['good', 'python', 'I', 'like', 100, 3]

    >>> len(a)

    6

    >>> a[6:]=['xxoo']

    >>> a

    ['good', 'python', 'I', 'like', 100, 3, 'xxoo']

    1.7.5 列表的函数

    什么是方法?方法和函数有什么区别?这里暂不区分和解释。请把

    这个名词“方法”抽象出来,等到后面自然明了(下面的内容中,没有区

    分“函数”和“方法”,读者不要介意这个名词)。

    列表是Python中的苦力,那么它都有哪些函数呢?或者对它能做什

    么呢?

    >>> dir(list)

    ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

    上面的结果中,以双下画线开始和结尾的暂时不管,如

    __add__(以后会管的)。就剩下以下几个了:

    'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'

    下面对这些函数进行说明和演示,这都是在编程实践中常常要用到

    的。1.append和extend

    前面提到的列表基本操作中有list.append(x),也就是将某个元素

    x追加到已知的一个列表的尾部。

    除了将元素追加到列表中,还能够将两个列表合并,或者说将一个

    列表追加到另外一个列表中。按照惯例,首先还是看官方文 ......

您现在查看是摘要介绍页, 详见PDF附件(7186KB,569页)