Python 3学习笔记(上卷)(txt+pdf+epub+mobi电子书下载)


发布时间:2021-04-03 00:15:01

点击下载

作者:雨痕

出版社:电子工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Python 3学习笔记(上卷)

Python 3学习笔记(上卷)试读:

前言

写作本书时,我已然摆脱“萌新”身份,算是稍有经验的作者。可即便如此,我依然无法保证本书的内容完全正确,且满足所有人的胃口。显然,这不可能做到。

在我看来,图书大抵分两类:学习和研究。学习类书籍满足日常学习和提升需要,用简练的语言把问题说清楚。最关键的是有清晰的线索,把散乱的知识串联起来,学习者可据此了解前因后果。至于研究类图书或论文,则应摆脱基础,摆脱语法,重点关注算法、架构、性能,乃至内部实现。所有这些,均以思想为支撑,超脱语言窠臼,构建并完善体系。

不同于写散文或小说,技术类图书的文字不好组织。自然语言易阅读,但不便描述有复杂流程分支的逻辑,易导致歧义。更何况,这其中还有各种转译带来的麻烦。故技术类图书应以自然语言开宗明义,阐述理论与规则,随后用代码对这段文字进行解释,毕竟代码先天有描述逻辑的优势。

很多书,尤其是英文版的图书,习惯于用大量篇幅对代码示例做各种讲解。我感觉这有些啰唆,想必很少有人去读第二遍,大家最多也就是用记号笔画出重点而已。既然如此,我们为何不信读者能阅读并理解这些代码呢?这本来就是程序员吃饭的本钱,最多在关键位置辅以注释便可。当然,阅读前提怕是要设定为非入门读者。好在我一再强调自己写的是第二本书,或曰“闲书”。

在本书中,对于理论层面,我会尝试说得明白些。当然,书中还会引入一些类比,这些类比或许不是非常合适,但却可以加深读者对相关问题的理解,毕竟不是所有人都能明白那些云里雾里的抽象理念。一如上面所言,文字与代码相辅相成,我们应静下心来用代码去验证文字背后的含义。在我眼里,代码也是一种自然语言,缩排跳转仿若图形,本就是最好的笔记注释。起码它离机器语言上有些距离,是为了便于人类阅读而发明的。

无论我说得多悦耳动听,这终归只是一本学习笔记,算不上专业,仅适合读者闲暇时翻阅一二。

关于本书

全套书分为上下两卷。上卷以语言为主,基本涵盖语言相关内容,包括语法、测试、调试,乃至解释器等层面的基本知识。下卷计划以标准库、优秀扩展库、并发编程,以及架构设计展开,算是对上卷“闲书”稍加修正。

书中示例运行环境:macOS 10.12,CPython 3.6,IPython 6.2

鉴于不同运行环境的差异性,示例输出结果(尤其是id、内存地址等信息)会有所不同。另外,为阅读方便,本书对输出结果做了裁剪处理,请以实际运行结果为准。

读者定位

本书着重于剖析语言的相关背景和实现方式,适合有一定 Python 编程基础的读者(比如准备从Python 2.7升级到Python 3.6环境的读者)阅读。至于初学者,建议寻找从零开始、循序渐进地介绍如何编写代码的其他图书为佳。

联系方式

鄙人能力有限,书中难免存在错漏之处。读者如在阅读过程中发现任何问题,请与我联系,以便更正。谢谢!

·邮件:qyuhen@hotmail.com

·微博:weibo.com/qyuhen雨 痕二〇一七年,仲秋读者服务

轻松注册成为博文视点社区用户(www.broadview.com.cn),扫码直达本书页面。

·提交勘误:您对书中内容的修改意见可在提交勘误处提交,若被采纳,将获赠博文视点社区积分(在您购买电子书时,积分可用来抵扣相应金额)。

·交流互动:在页面下方读者评论处留下您的疑问或观点,与我们和其他读者一同学习交流。

页面入口:http://www.broadview.com.cn/33274上卷 语言详解基于Python 3.6第1章 概述

Python是一门相当有趣的编程语言。

其始于 1989 年末,约莫而立之年,比许多程序员的年龄还要大。在这段漫长的时光里,它见证了 C++的兴盛和群雄大战,看到了 Java 的异军突起和如日中天,更有同类Ruby凭借 RoR 领一时风骚,还有习惯丢三落四却每每笑到最后的VC被同族怼得灰头土脸。

在这期间还发生过什么?面向对象、设计模式、多层架构、面向服务等数不清的概念和名词。以程序界的划代标准,这已然是一个早该供在 WiKi 里的老古董,偶尔被某个年纪大的前辈拉出来讲古。然而,历经世事变幻,一朵朵“白莲花”最终都免不了闹个“腹黑”收场。就连当年那些无敌论的吹鼓手,如今都成了大肆指摘的异见人士。

且不管风云如何,Python活得很好,依旧占据排行榜前列,可见其不全然是一部遗存的程序设计编年史。Python不仅能当“胶水”写工具脚本,还借着大数据、深度学习、机器学习和人工智能的风潮,一跃成为当红之选。

当然,事物总有两面性。一方面,我们能从雨后春笋般出现的新技术支持名单里找到它的身影;而另一面,身边似乎并无多少人去使用或关注它。它被推荐给孩子作为编程入门语言,也被专业人士用于特定场合,可恰恰在靠编程吃饭的程序员主战场上位置尴尬。其虽然有浩如烟海的第三方支持,但说起来似乎只有系统维护和网站应用。所有这些,让我们对这门语言既熟悉又陌生。

喜欢它的各有因由,批评的则火力集中。在各大社区里,不乏有人对其性能、语法,乃至千年话题全局锁大加指责,以烘托某种语言才是更好的选择。这源自部分开发人员,尤其是新人追求大而全的心理,缺乏理性定位。历史上,还从没有一种语言能包办所有应用,更不曾讨好过所有人。

作为应用语言,脑门还刻着简单和优雅字号,自然要支持各时期的主流编程范式,竭力涵盖各类应用范畴,还需大费周章将复杂封装并隐藏起来,以期换取惯常喜新厌旧的程序员垂青。所以,从中你能看到命令式、函数式、面向对象、面向切面等程序设计方式。这造就了其广泛的支持,也带来易学难精的后果。历史包袱出现在所有步入中年的技术身上,其中有操作系统,有浏览器,自然也有编程语言。呼吁某某减肥和变革的声音不绝于耳,而后是新生代迈着轻盈的步伐后来居上。

可换个角度看,正因为与时俱进和兼容并蓄,方能存活至今。那些特立独行的,反倒未必笑到最后。君不见,方兴未艾的各路 NoSQL 不但因功能单一而横遭嫌弃,还遭看似老朽的“革命对象” RDBMS 反戈一击。要么纯粹享受寂寞,要么广博得汇溪成海。以“色”娱人,能讨巧于一时,终难长久。人们总有个错觉,似乎新技术是凭空出现,是年轻人的主场。但实际上,其依托早已存世,或埋于地下,或束之高阁,且待时机。

Python的简单和周全,降低了非专业人士的使用门槛,毕竟他们的精力不会放在语言身上。此时,广泛支持就成为优点,即便不了解面向对象,也可用面向过程写点什么。更何况,那令人咋舌的生态系统里,总能找到你需要却又无法实现的东西。相当有趣的是,很有些专业扩展库,恰恰是用程序员看不上眼的代码完成的。兴许,作者只是个数学家,或图形学方面的天才。是以,任何一种设计都有其出现的原因和存在的理由。

在国内,将 Python 当作主力编程语言的人群很有限,其影响力和热度甚至不如某些后来者。这固然有其自身的种种原因,可社区疲软也显而易见。不管境况如何,难得有这样一门能长久陪伴,且行事周全的语言用于工作和学习,大家须珍惜。

Python 3

如果你对Python 3的了解尚停留在数年以前,那是时候更新一下认知了。下面这样一段文字,或许可代表生态圈的主流态度。

What Python version should I use with Django ?

Python 3 is recommended.Django 1.11 is the last version to support Python 2.7.Support for Python 2.7 and Django 1.11 ends in 2020.

Since newer versions of Python are often faster,have more features,and are better supported,the latest version of Python 3 is recommended.

You don’t lose anything in Django by using an older release,but you don’t take advantage of the improvements and optimizations in newer Python releases.—— Django FAQ

最初,迁入Python 3的阻碍可能是某个扩展库不支持,这也是很多人的主要理由。但到了今天,在Python 3 Readiness所统计的最流行的360个包里,有超过95%支持Python 3。起码对于新项目,这已不是问题。

另一个理由,应该是Python 3早期那让人失望的性能。可自2008年发布,至今9年,期间经多个版本的优化改进,其性能改善良多,早已不再是“弱鸡”的形象。

尽管在多年前,官方将Python 2.7 EOL(end of life)推迟到2020年。可晃悠至今,所余时间已不足三年。即便因某些原因再度推迟,那也不是新项目继续使用2.7的理由,因为不会再有Python 2.8。

还有,Python 3的asyncio已成为主流异步框架。众多Web Framework、Database Driver等都已提供支持,并获得更好的执行性能。至于那些新增的、改进的,被摒弃且不合时宜的,等等,都值得我们去了解和尝试一下。

Python 3 Readiness:http://py3readiness.org/

Python Speed Center:https://speed.python.org/

Python 3.6 & Performance:http://igordavydenko.com/talks/by-pycon-2017/

Python 2.7 Countdown:https://pythonclock.org/

PEP 373:http://legacy.python.org/dev/peps/pep-0373/第2章 类型2.1 基本环境

作为一种完全面向对象,且兼顾函数式的编程语言,Python的复杂程度要远高出许多人的设想,诸多概念被隐藏在看似简单的代码背后。为了更好且更深入地理解相关规则,在讲述语言特征以前,我们需对世界背景做初步的了解。2.1.1 印象

从抽象角度来看,每个运行中的程序(进程)都由数量众多的“鲜活”对象组成。每个对象都有其独特状态和逻辑,通过行为触发,或与其他对象交互来体现设计意图。面对众多个体,作为设计师自然要以宏观视角来规划世界。这里首先要做的,就是将所有个体分门别类归置于不同族群。

我们习惯将生物分为动物、植物,进而又有猫科、犬科等细分。通过对个体的研究,归纳其共同特征,抽象成便于描述的种族模板。有了模板后,可据此创建大量行为类似的个体。所以,分类是个基础工程。

在专业术语上,我们将族群或类别称作类型(class),将个体叫作实例(instance)。类型持有同族个体的共同行为和共享状态,而实例仅保存私有特性即可。如此,在内存空间布局上才是最高效的。

以张三、李四为例。在创建抽象模型时,人类的共有特征,诸如吃饭、走路等,统统放到“人类”这个类型里。个体只保存姓名、性别、胖瘦、肤色这些即可。

每个实例都持有所属类型的指针。需要时,通过它间接访问目标即可。但从外在逻辑接口看,任何实例都是“完整”的。

存活实例对象都有“唯一”ID值。

不同Python实现使用不同算法,CPython用内存地址作为ID值。这意味着它只能保证在某个时间,在存活对象里是唯一的。它不保证整个进程生命周期内的唯一,因为内存地址会被复用。因此,ID就不适合作为全局身份标识。

可用type返回实例所属的类型。

要判断实例是否属于特定类型,可使用isinstance函数。

类型间可构成继承关系。就像老虎继承自猫科,而猫科又继承自哺乳动物,往上还有更顶层的类型。继承关系让类型拥有其所有祖先类型的特征。因历史原因,Python允许多继承,也就是说可有多个父类型,好似人类同时拥有父族、母族遗传特征。

任何类型都是其祖先类型的子类,同样,对象也可以被判定为其祖先类型的实例。这与面向对象三大特性中的多态有关,后面再做详述。

事实上,所有类型都有一个共同祖先类型 object,它为所有类型提供原始模板,以及系统所需的基本操作方式。

类型虽然是抽象族群概念,但在实现上也只是个普通的对象实例。区别在于,所有类型都是由type创建的,这与继承无关。

怎么理解呢?单就类型对象而言,其本质就是用来存储方法和字段成员的特殊容器,用同一份设计来实现才是正常思路。

这就好比扑克牌,从玩法逻辑上看,J、Q、K、A等都有不同含义。但从材质上看,它们完全相同,没道理用不同材料去制作这些内容不同的卡片。同理,继承也只是说明两个类型在逻辑上存在关联关系。如此,所有类型对象都属于 type 实例就很好理解了。

无论是编码,还是设计,都要正确区分逻辑与实现的差异。

当然,类型对象属于创建者这样的特殊存在。默认情况下,它们由解释器在首次载入时自动生成,生命周期与进程相同,且仅有一个实例。2.1.2 名字

在通常认知里,变量是一段具有特定格式的内存,变量名则是内存别名。因为在编码阶段,无法确定内存的具体位置,故使用名称符号代替。

注意变量名与指针的不同。

接下来,静态编译和动态解释型语言对于变量名的处理方式完全不同。静态编译器或链接器会以固定地址,或直接、间接寻址指令代替变量名。也就是说变量名不参与执行过程,可被剔除。但在解释型动态语言里,名字和对象通常是两个运行期实体。名字不但有自己的类型,还需分配内存,并介入执行过程。甚至可以说,名字才是动态模型的基础。

如果将内存寻址比喻成顾客按编号直接寻找服务柜台,那么名字就是一个接待员。任何时候,顾客都只能通过他间接与目标服务互动。从表面看,这似乎是高级会员待遇,但实际增加了中间环节和额外开销,于性能不利。但好处是,接待员与服务之间拥有更多的可调整空间,可用来增加代理和安全机制,甚至为缓存管理提供机会,具体可参考本书后续章节有关元编程的内容。

当然,名字必须与目标对象关联起来才有意义。

最直接的关联操作就是赋值,而后对名字的引用都被解释为对目标对象进行操作。

赋值步骤:

1.准备好右值目标对象(100)。

2.准备好名字(x)。

3.在名字空间里为两者建立关联(namespace{x:100})。

即便如此,名字与目标对象之间也仅是引用关联。名字只负责找人,但对于此人一无所知。鉴于在运行期才能知道名字引用的目标类型,所以说Python是一种动态类型语言。

Names have no type,but objects do.

名字空间

名字空间(namespace)是上下文环境里专门用来存储名字和目标引用关联的容器。

对Python而言,每个模块(源码文件)都有一个全局名字空间。而根据代码作用域,又有当前名字空间或本地名字空间一说。如果直接在模块级别执行,那么当前名字空间和全局名字空间相同。但在函数內,当前名字空间就专指函数作用域。

名字空间默认使用字典(dict)数据结构,由多个键值对(key/value)组成。

内置函数globals和locals分别返回全局名字空间和本地名字空间字典。

可见,globals总是固定指向模块名字空间,而locals则指向当前作用域环境。

在初步了解后,我们甚至可直接修改名字空间来建立关联引用。这与传统变量定义方式有所不同。

并非所有时候都能直接操作名字空间。函数执行使用缓存机制,直接修改本地名字空间未必有效。在正常编码时,应尽可能避免直接修改名字空间。

在名字空间字典里,名字只是简单字符串主键,其自身数据结构里没有任何目标对象信息。通过名字访问目标对象,无非是以名字为主键去字典里读取目标对象指针引用。也正因如此,名字可重新关联另一对象,完全不在乎其类型是否与前任相同。

赋值操作仅是让名字在名字空间里重新关联,而非修改原对象。

和一个名字只能引用一个对象不同,单个对象可以同时有多个名字,无论是在相同或不同的名字空间里。

一个人在办公室里(名字空间)的名字可以是老王、王大虎,等等,这时,这个人在单一空间里有多个名字。出了办公室,在全公司(另一名字空间)范围内,他还可有王处长等其他名字。

必须使用is判断两个名字是否引用同一对象。相等操作符并不能确定两个名字指向同一对象,这涉及操作符重载,或许仅用来比较值是否相等。

命名规则

名字应选用有实际含义,且易于阅读和理解的字母或单词组合。

·以字母或下画线开头。

·区分大小写。

·不能使用保留关键字(reserved word)。

为统一命名风格,建议:

·类型名称使用CapWords格式。

·模块文件名、函数、方法成员等使用lower_case_with_underscores格式。

·全局常量使用UPPER_CASE_WITH_UNDERSCORES格式。

·避免与内置函数或标准库的常用类型同名,因为这样易导致误解。

尽管Python 3支持用中文字符作为名字,但这并不是好选择。

保留关键字如下:

提示:Python 2.x里的exec、print,在Python 3.x里已变成函数,不再是保留字。

如要检查动态生成代码是否违反保留字规则,可用keyword模块。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载