20.3 小结

在本章中,你学习了如何使用Bootstrap库和应用程序django-bootstrap4赋予应用程序简单而专业的外观。使用Bootstrap意味着无论用户使用哪种设备来访问你的项目,你选择的样式都将实现几乎相同的效果。

你学习了Bootstrap的模板,并使用模板Navbar static赋予了“学习笔记”简单的外观。你学习了如何使用jumbotron来突出主页中的消息,还学习了如何给网站的所有页面设置一致的样式。

在本章最后一节,你学习了如何将项目部署到Heroku服务器,让任何人都能够访问。你创建了一个Heroku账户,并安装了一些帮助管理部署过程的工具。你使用Git将能够正确运行的项目提交到仓库,再将这个仓库推送到Heroku的服务器。最后,你将DEBUG 设置为False ,以确保在线应用程序的安全。

开发完项目“学习笔记”后,你就能自己动手开发项目了。请先让项目尽可能简单,确定它能正确运行后,再添加复杂的功能。愿你学习愉快,开发项目时有好运相伴!

附录 A 安装与故障排除

20.3 小结 - 图1  Python有不同的版本,在各种操作系统中有很多安装方式。如果第1章介绍的方式不管用,或者要安装非系统自带的Python版本,本附录可提供帮助。

A.1 Windows系统

第1章的安装说明指出了如何使用Python网站提供的官方安装程序安装Python。如果执行安装程序后,无法运行Python,本节的故障排除说明将帮助你让Python恢复正常。

A.1.1 查找Python解释器

如果执行简单命令python 时出现错误消息,如python 不是可识别的内部或外部命令(python is not recognized as an internal or external command),很可能是因为执行安装程序时没有选中复选框Add Python to PATH。在这种情况下,需要告诉Windows去哪里查找Python解释器。要确定Python解释器的位置,请打开C盘,并在其中查找名称以Python打头的文件夹。(要找到这样的文件夹,可能需要在Windows资源管理器的搜索栏中输入单词python,因为它可能不在C盘的根目录下。)打开这个文件夹,并查找名称为python(全部小写)的文件。右击这个文件并选择“属性”,你将在“位置”后面看到它的路径。

要告诉Windows去哪里查找解释器,可以打开一个终端窗口,输入刚才看到的路径,再输入-version ,并按回车键:

$ C:\Python37\python —version
Python 3.7.2


在你的系统中,这条路径可能类似于下面这样:C:\Users\username\Programs\Python37\python 。指定路径后,Windows应该会运行Python解释器。

A.1.2 将Python添加到环境变量Path

如果每次启动Python终端会话时都需要输入完整的路径,那就太讨厌了。因此,我们将在系统中添加这个路径,让你只需使用命令python 即可。打开控制面板并单击“系统和安全”,再单击“系统”。单击“高级系统设置”,在打开的窗口中单击按钮“环境变量”。

在“系统变量”部分,找到并单击变量Path ,再单击按钮“编辑”。你将看到一系列位置,而系统将在这些位置查找程序。单击“新建”按钮,并将文件python.exe的路径粘贴到出现的文本框中。如果你的系统设置与我的一样,这条路径应该是这样的:

C:\Python37


请注意,这里没有指定文件名python.exe,而只是告诉系统到哪里去查找它。

关闭终端窗口,再打开一个新的终端窗口。这将在终端会话中加载变量Path 的新值。现在执行命令python —version 时,你将看到刚才在变量Path 中设置的Python版本。现在,只需在命令提示符下输入python 并按回车,就可启动Python终端会话了。

注意  如果你使用的是较早的Windows版本,则单击“编辑”按钮时,出现的对话框可能包含文本框“变量”。如果是这样,请使用右箭头键滚动到最右边。千万不要覆盖变量原来的值。如果不小心覆盖了,请单击“取消”按钮,再重复前面的步骤。在变量值的末尾添加一个分号,再添加文件python.exe的路径,如下所示:
%SystemRoot%\system32...\System32\WindowsPowerShell\v1.0\;C:\Python37


A.1.3 重装Python

如果还是无法运行Python,卸载Python并再次执行安装程序通常能解决所有的问题。为此,打开“控制面板”并单击“程序和功能”,再向下滚动,找到并选择刚才安装的Python版本。单击“卸载/更改”,在出现的对话框中单击“卸载”。然后,按第1章的说明再次执行安装程序,并确保选择了复选框Add Python to PATH以及其他与系统相关的设置。如果还是无法运行Python,又不知道到哪里去寻求帮助,请参阅附录C的建议。

A.2 macOS系统

第1章的安装说明让你使用Python网站提供的安装程序,我推荐你这样做,除非有特殊原因。另一种方法是使用Homebrew,在macOS系统中,可使用这个工具来安装各种软件。如果你使用过Homebrew并想使用它来安装Python,或者有同事在使用Homebrew而你也想安装它,请参阅接下来的说明。

A.2.1 安装Homebrew

Homebrew依赖于Apple Xcode包中的一些命令行工具,因此你需要先安装Xcode命令行工具。为此,打开一个终端窗口并执行如下命令:

$ xcode-select —install


在不断出现的确认对话框中都单击OK按钮。(根据网络连接的速度,这可能持续一段时间。)接下来执行如下命令以安装Homebrew:

$ usrbin/ruby -e "$(curl -fsSL
https://raw.githubusercontent.com/Homebrew/install/master/install)"


这个命令可在Homebrew网站找到。务必在curl -fsSL 和URL 之间包含一个空格。

注意  这个命令中的-e 让Ruby(Homebrew就是使用这种编程语言编写的)执行下载的代码。除非来源是你信任的,否则不要运行这样的命令。

为确认正确地安装了Homebrew,请执行如下命令:

$ brew doctor
Your system is ready to brew.


上述输出表明,可以使用Homebrew在系统中安装包了。

A.2.2 安装Python

为安装最新的Python版本,请执行如下命令:

$ brew install python


使用下面的命令检查安装的是哪个版本:

$ python3 —version
Python 3.7.2
$


现在,可以使用命令python3 来启动Python终端会话了,还可以使用命令python3 来配置文本编辑器,使其使用刚安装的Python版本(而不是系统自带的版本)来运行Python程序。如果不知道如何配置Sublime Text来使用刚安装的Python版本,请参阅第1章的说明。

A.3 Linux系统

几乎所有Linux系统都默认安装了Python,但如果自带的版本低于Python 3.6,就需要安装最新的版本。下面的说明适用于大多数基于apt的系统。

你将使用名为deadsnakes 的包,它能让你轻松地安装多个Python版本。请执行如下命令:

$ sudo add-apt-repository ppa:deadsnakes/ppa
$ sudo apt-get update
$ sudo apt install python3.7


这些命令将在你的系统中安装Python 3.7。

执行下面的命令启动一个运行Python 3.7的终端会话:

$ python3.7
>>>


配置文本编辑器使其使用Python 3.7以及从终端运行程序时,也需要用到这个命令。

A.4 Python关键字和内置函数

Python包含一系列关键字和内置函数,给变量命名时,知道这些关键字和内置函数很重要:不能将Python关键字用作变量名,也不应将Python内置函数的名称用作变量名,否则将覆盖相应的内置函数。

本节将列出Python关键字和内置函数的名称,让你知道应避免使用哪些变量名。

A.4.1 Python关键字

下面的关键字都有特殊含义,如果将它们用作变量名,将引发错误:

False await else import pass
None break except in raise
True class finally is return
and continue for lambda try
as def from nonlocal while
assert del global not with
async elif if or yield


A.4.2 Python内置函数

将内置函数名用作变量名时,不会导致错误,但将覆盖这些函数的行为:

abs() delattr() hash() memoryview() set()
all() dict() help() min() setattr()
any() dir() hex() next() slice()
ascii() divmod() id() object() sorted()
bin() enumerate() input() oct() staticmethod()
bool() eval() int() open() str()
breakpoint() exec() isinstance() ord() sum()
bytearray() filter() issubclass() pow() super()
bytes() float() iter() print() tuple()
callable() format() len() property() type()
chr() frozenset() list() range() vars()
classmethod() getattr() locals() repr() zip()
compile() globals() map() reversed() import()
complex() hasattr() max() round()


附录 B 文本编辑器与IDE

20.3 小结 - 图2  程序员要花费大量时间编写、阅读和编辑代码,因此必须使用文本编辑器或集成开发环境 (IDE)来尽可能提高效率。好的编辑器会做些简单的工作,如突出代码结构,帮助你在编程期间发现常见的bug,但是又不会做得太多,以免打断你的思路。编辑器还提供了一些很有用的功能,如自动缩进、标识出合适的行长以及提供常用操作的快捷键。

IDE是一种提供了大量其他工具(如交互式调试器和代码检视器)的文本编辑器。IDE在你输入代码时对其进行检查,力图弄清你创建的项目是什么样的。例如,当你输入函数名时,IDE可能显示该函数接受的所有参数。在一切顺利且你明白显示的内容时,这可能很有帮助。不过对初学者来说,这可能是极大的负担,因为他们可能不明白为何在IDE中输入的代码不可行。

我建议你在学习编程期间使用简单的文本编辑器。文本编辑器给系统带来的负担轻得多,因此如果你使用的计算机较旧或配置的资源有限,文本编辑器运行起来将比IDE顺畅得多。如果你熟悉IDE或者周围有人在使用IDE而你也想在这样的环境中编程,则完全可以尝试使用IDE。

就目前而言,不用太操心工具选择的问题,还不如将时间花在深入了解Python语言和开发感兴趣的项目上。掌握基础知识后,就会更清楚什么样的工具适合你。

本附录介绍如何配置文本编辑器Sublime Text,以提高工作效率。最后还将简单介绍众多其他编辑器,你可能会考虑使用它们或者看到其他Python程序员使用它们。

B.1 自定义Sublime Text设置

在第1章,你配置了Sublime Text,使其使用所需的Python版本来运行程序。下面来配置其他方面,让Sublime Text完成本附录开头提到的一些工作。

B.1.1 将制表符转换为空格

如果在代码中混用制表符和空格键,可能导致程序出现难以调试的问题。为避免这种情况发生,可配置Sublime Text,使其总是使用空格来缩进,即便你按下Tab键亦如此。为此,打开菜单View ▶ Indentation,核实选择了Indent Using Spaces。如果没有,现在选择就它,并确保将Tab Width设置为4个空格。

如果你已经在程序中混用了制表符和空格,可将所有制表符都转换为空格,方法是选择菜单View ▶ Indentation ▶ Convert Tabs to Spaces。也可通过单击Sublime Text窗口右下角的Spaces字样来访问这些设置。

现在如果按Tab键来缩进代码行,Sublime Text将自动将制表符转换为指定数量的空格。

B.1.2 设置行长标志

大多数编辑器允许你设置视觉线索(通常是竖线),指出代码行应在哪里结束。在Python社区,这方面的约定是行长不要超过79字符。要设置这种标志,可打开菜单View ▶ Ruler,再选择80。Sublime Text将在第80字符标志处放置一条竖线,帮助确保代码行的长度是合适的。

B.1.3 缩进和取消缩进代码块

要缩进代码块,可选择它,再选择菜单Edit ▶ Line ▶ Indent或按Ctrl + ](macOS系统中为Command + ])。要取消缩进代码块,可选择菜单Edit ▶ Line ▶ Unindent或按Ctrl + [(macOS系统中为Command + [)。

B.1.4 将代码块注释掉

要暂时禁用代码块,可选中它并注释掉,从而让Python忽略它。通过选择菜单Edit ▶ Comment ▶ Toggle Comment或按Ctrl + (macOS系统中为Command + ),可将选定的代码行注释掉:在行首添加井号(#),并保持缩进程度不变,以指出这不是常规注释。要对代码块取消注释,可选中它,并再次选择前述菜单项。

B.1.5 保存配置

前面提到的一些设置只影响当前文件,要让设置影响所有在Sublime Text中打开的文件,需要定义用户设置。为此选择菜单Preferences ▶ Settings,找到文件Preferences.sublime-settings – User,并在其中输入如下内容:

{
"rulers": [80],
"translate_tabs_to_spaces": true
}


保存这个文件,则指定的标尺和制表符设置将被应用于在Sublime Text中打开的所有文件。在这个文件中添加设置时,确保每行都以逗号结尾,但最后一行例外。你可以在网上查看其他用户的设置文件,进而自定义编辑器,以最大限度地提高工作效率。

B.1.6 进一步自定义

你能以众多方式自定义Sublime Text,进一步提高工作效率。探索菜单时,要留意最常用的菜单项的键盘快捷键。通过使用键盘快捷键而不是鼠标或触摸板来执行操作,可提高效率。不要试图一次性记住所有的快捷键,只需记住最常执行的操作的快捷键就行,同时看看有没有其他功能可帮助你改善工作流程。

B.2 其他文本编辑器和IDE

你肯定会听说众多其他的文本编辑器,或者看到有人使用这些编辑器。对于这些编辑器,通常可像自定义Sublime Text那样进行配置。下面介绍你可能听人说到的一些文本编辑器。

B.2.1 IDLE

IDLE是Python自带的文本编辑器。相比于Sublime Text,它不那么直观,但有些初学者教程可能会提到它,因此你可能想试一试。

B.2.2 Geany

Geany是一款简单的编辑器,你可在其中直接运行所有的程序。它在终端窗口中显示所有输出,有助于你逐渐习惯使用终端。Geany的界面非常简单,但功能强大,因此很多经验丰富的程序员也在使用它。

B.2.3 Emacs和Vim

Emacs和Vim是两款流行的编辑器,深受众多经验丰富的程序员喜爱,因为使用它们时,用户的手根本不用离开键盘。因此学会使用这些编辑器后,编写、阅读和编辑代码的效率将获得极大提高。不过这也意味着学会使用它们的难度极大。大多数Linux和macOS计算机自带Vim,而且Emacs和Vim都可完全在终端中运行,因此它们常被用来通过远程终端会话在服务器上编写代码。

程序员通常会推荐你试一试它们,但很多编程老手忘了编程新手要学习的东西实在太多了。知道这些编辑器是有益的,但请先使用简单编辑器,以便专注于学习编程,而不是费时间去学习如何使用编辑器。等你能够熟悉地编写和编辑代码后,再去使用这些编辑器吧。

B.2.4 Atom

Atom是一款文本编辑器,但提供了一些通常只有IDE才提供的功能。在Atom中,可以打开单个文件,也可打开项目文件夹并轻松地访问项目中所有的文件。Atom集成了Git和GitHub,在需要使用版本控制时,这让你在编辑器中就能使用本地仓库和远程仓库,无须切换到另一个终端窗口。

Atom还允许你安装包,从而以众多方式扩展其功能。可安装的包有很多,这让Atom更像一个IDE。

B.2.5 Visual Studio Code

Visual Studio Code(VS Code)也是一款类似于IDE的编辑器,让你能够高效地使用调试器,还集成了版本控制功能并提供了代码补全工具。

B.2.6 PyCharm

PyCharm是一款深受Python程序员欢迎的IDE,因为它是专门为使用Python编程而开发的。完整版需要付费订阅,但很多开发人员觉得免费的社区版(PyCharm Community Edition)也很有用。

PyCharm提供了一个linter ,它检查编码是否遵循了普遍接受的Python编程约定,并在代码不符合Python代码格式设置时提出修改建议。它集成了调试器,旨在帮助你高效消除错误,还支持各种模式,让你能够高效地使用众多流行的Python库。

B.2.7 Jupyter Notebook

Jupyter Notebook不属于传统的文本编辑器或IDE,而是一款主要由块组成的Web应用程序。每个块都要么是代码块,要么是文本块,其中的文本块采用Markdown格式,让你能够设置简单的文本格式。

最初开发时,Jupyter Notebook旨在支持在科学应用程序中使用Python,但经过不断的扩展后,它在很多情形下都很有用。在Jupyter Notebook中,不仅可在.py文件中添加注释,还可编写带简单格式的文本,如标题、带项目符号的列表和在不同代码片段之间导航的超链接。每个代码块都可独立运行,让你能够测试程序的一小部分或同时运行所有的代码块。每个代码块都有独立的输出区域,可根据需要显示或隐藏。

Jupyter Notebook不同单元格(cell)之间的交互有时可能会令你迷惑。例如,如果在一个单元格中定义了一个函数,在其他单元格中也可使用。这在大多数情况下是有益的,但如果Notebook很长,而你又对Notebook环境的工作原理没有全面的认识,就会感到迷惑。

如果你使用Python进行科学编程或以数据为核心的编程,肯定会遇到Jupyter Notebook。

附录 C 寻求帮助

20.3 小结 - 图3  每个人学习编程时都会遇到困难,因此作为程序员,需要学习的最重要的技能之一就是如何高效地摆脱困境。本附录简要介绍几种帮助你摆脱编程困境的方法。

C.1 第一步

陷入困境后,首先需要判断形势。向别人寻求帮助前,请回答如下三个问题。

  • 你想要做什么?
  • 你已尝试哪些方式?
  • 结果如何?

答案应尽可能具体。对于第一个问题,像“我要在Windows 10笔记本计算机上安装最新版Python”这样明确的陈述足够详细,让Python社区的其他人员能够施以援手;而像“我要安装Python”这样的陈述则没有提供足够的信息,让别人无法提供太多帮助。

对于第二个问题,答案应提供足够多的细节,这样别人就不会建议你去重复尝试过的方式:相比于“我访问Python网站,并下载了一些东西”,“我访问Python官方网站的下载页面,单击针对我所使用系统的Download按钮,再运行安装程序”提供的信息更详细。

对于第三个问题,知道准确的错误消息很有用,因为这样可在线搜索错误消息以寻找解决方案,也可在向别人寻求帮助时提供错误消息。

有时候,只需要回答这三个问题,你就能发现遗漏了什么,无须求助就能摆脱困境。程序员甚至给这种情形取了一个名字:橡皮鸭子调试法 。如果向一只橡皮鸭子(或任何无生命的东西)清楚地阐述自己的处境,并提出具体的问题,常常能够回答这个问题。有些编程公司甚至会在办公室放置一个橡皮鸭子,旨在鼓励程序员“与这只鸭子交流”。

C.1.1 再试试

只需回过头去重新来一次,就足以解决很多问题。假设你在模仿本书的一个示例编写for 循环时,可能遗漏了某种简单的东西,如for 语句末尾的冒号。再试一次可能就会帮助你避免重复同样的错误。

C.1.2 歇一会儿

如果你很长时间内一直在试图解决同一个问题,那么休息一会儿实际上是你可采取的最佳战术。长时间从事一个任务时,你可能变得一根筋,脑子里想的都是一个解决方案。你往往会对所做的假设视而不见,而休息一会儿有助于你从不同的角度看问题。不用休息很长时间,只要能够摆脱当前的思维方式就行。如果你坐了很长时间,就起来做做运动:散散步或者去室外待一会儿,也可以喝杯水,或者吃点清淡而健康的零食。

如果你心情沮丧,也许该将工作放到一边,整天都不再考虑。晚上睡个好觉后,你常常会发现问题并不是那么难以解决。

C.1.3 参考本书的在线资源

本书提供了配套的在线资源,网址为ituring.cn/book/2784,其中包含大量有用的信息,比如如何设置系统以及如何解决每章可能遇到的难题。如果你还没有查看这些资源,现在就去吧,看看它们能否提供帮助。

C.2 在线搜索

很可能有人遇到过你面临的问题,并在网上发表了相关的文章。良好的搜索技能和具体的关键词有助于找到现有的资源,帮助解决你面临的问题。例如,如果无法在Windows 10系统中安装最新版Python,搜索“Windows 10 安装Python)并将结果限定为一年内,可能让你找到清晰的解决方案。

使用计算机显示的错误消息进行搜索也很有帮助。例如,假设你试图启动Python终端会话时出现了如下错误消息:

> python
'python' is not recognized as an internal or external command,
operable program or batch file
>


通过搜索完整的错误消息“python is not recognized as an internal or external command”,也许能得到不错的建议。

搜索与编程相关的主题时,有几个网站会反复出现。下面简要地介绍一下这些网站,让你知道它们可能提供什么样的帮助。

C.2.1 Stack Overflow

Stack Overflow是最受程序员欢迎的问答网站之一,当你执行与Python相关的搜索时,它常常会出现在第一个结果页中。Stack Overflow的成员在陷入困境时提出问题,其他成员会努力提供有帮助的答案。用户可推荐其认为最有帮助的答案,因此前几个答案通常就是最佳答案。

对于很多基本的Python问题,在Stack Overflow上有非常明确的答案,因为这个社区在不断改进。它鼓励用户发布更新的帖子,因此这里的答案通常与时俱进。本书编写期间,Stack Overflow回答的与Python相关的问题超过了一百万个。

C.2.2 Python官方文档

对初学者来说,Python官方文档显得有点漫不经心,因为其主要目的是阐述这门语言,而不是进行解释。官方文档中的示例应该很有用,但你也许不能完全弄懂。虽然如此,这还是一个不错的资源,如果它出现在搜索结果中,就值得你去参考;另外,随着你对Python的认识越来越深入,这个资源的用处将越来越大。

C.2.3 官方库文档

如果你使用了库,如Pygame、Matplotlib和Django等,搜索结果中通常会包含到其官方文档的链接。例如,Django文档就很有用。如果你要使用这些库,最好熟悉其官方文档。

C.2.4 r/learnpython

Reddit包含很多子论坛,这些子论坛称为subreddit ,其中的r/learnpython非常活跃,提供的信息也很有帮助。你可以在这里阅读其他人提出的问题,也可以提出自己的问题。

C.2.5 博客

很多程序员有博客,旨在与他人分享对自己所使用语言的心得。接受博客文章提供的建议前,应大致浏览一下前几条评论,看看别人的反馈。如果文章没有任何评论,请对其持保留态度——可能还没有人验证过其中的建议。

C.3 IRC

很多程序员通过IRC(Internet Relay Chat,互联网中继聊天)实时交流。如果你被问题困住,在网上搜索也找不到答案,那么在相关的IRC频道(channel)中寻求帮助可能是最佳选择。这些频道里的人大多彬彬有礼、乐于助人,在你能够详细地描述要做什么、尝试了哪些方法及其结果时尤其如此。

Python主频道是#python 。频道##learnpython(两个井号)也非常活跃。这个频道与r/learnpython/相关联,因此你在其中也将看到有关r/learnpython上帖子的消息。如果你正在开发Web应用程序,可能想加入频道#django。加入频道后,就可以看到其他人的交流,还可以提出问题。

要获得有效的帮助,你需要知道一些有关IRC文化的细节。将重点放在本附录开头所说的三个问题上,无疑有助于获得可行的解决方案。如果能准确地阐述你要做什么、尝试了哪些方法以及得到的结果,别人就会乐意伸出援手。为分享代码或输出,IRC成员会使用外部网站,如bPaste(#python通过它来分享代码和输出)。这能避免让频道到处都是代码,还让分享的代码阅读起来容易得多。一定要有耐心,这样别人才会更乐意帮助你。准确地提出问题,并等待别人来回答。虽然大家都在忙于交流,但总会有人及时回答你的问题。如果频道的参与者较少,可能要过一段时间才会有人回答你的问题。

C.4 Slack

Slack有点像现代版IRC,通常用于公司内部交流,但也有很多面向公众的讨论组。要查看Slack Python讨论组,可访问PySlackers网站,单击页面顶部的链接Slack,再输入电子邮箱地址以获取邀请函。进入Python Developers区后,将看到一个频道列表,你可单击Channels并选择感兴趣的主题。首先应加入的可能是频道#learning_python和#django。

C.5 Discord

Discord也是一个在线聊天环境。它包含一个Python社区,你可以在其中寻求帮助,还可以参加与Python相关的讨论。要进入该社区,可访问Python Discord网站,再单击页面右上角的DISCORD logo。在出现的屏幕中,有一个自动生成的邀请函。如果有Discord账户,可使用它登录;如果没有,请输入用户名并按提示完成Discord注册过程。首次访问Python Discord时,需要接受社区行为准则才能参与其中。完成注册并登录后,就能加入任何感兴趣的频道了。寻求帮助时,务必在Python Help频道发帖。

附录 D 使用Git进行版本控制

20.3 小结 - 图4  版本控制软件让你能够拍摄处于可行状态的项目快照。修改项目(如实现新功能)后,如果项目不能正常运行,可恢复到前一个可行状态。

通过使用版本控制软件,你可以放手去改进项目,不用担心项目因你犯错而遭到破坏。对大型项目来说,这显得尤其重要,但对于较小的项目,哪怕是只包含一个文件的程序,这也大有裨益。

在本附录中,你将学习如何安装Git,以及如何使用它来对当前开发的程序进行版本控制。Git是当前最流行的版本控制软件,包含很多高级工具,可帮助团队协作开发大型项目,但其最基本的功能也非常适合独立开发人员使用。Git通过跟踪对项目中每个文件的修改来实现版本控制,如果你犯了错,只需恢复到保存的前一个状态即可。

D.1 安装Git

Git可在所有操作系统上运行,但安装方法随操作系统而异。接下来的几小节详细说明了如何在各种操作系统中安装它。

D.1.1 Windows系统

可从Git网站下载Git安装程序。在这个网站中,你将看到下载链接,指向适合你的系统的安装程序。

D.1.2 macOS系统

macOS系统可能已经安装了Git,因此请尝试执行命令 git —version 。如果在输出中看到了具体的版本号,说明系统安装了Git;如果看到一条消息,提示你安装或升级Git,只需按屏幕上的说明做即可。

你也可以访问Git网站主页,将看到下载链接,指向适合你系统的安装程序。

D.1.3 Linux系统

要在Linux系统中安装Git,请执行如下命令:

$ sudo apt install git-all


这就行了。现在可以在项目中使用Git了。

D.1.4 配置Git

Git跟踪是谁修改了项目,哪怕参与项目开发的人只有一个。为此,Git需要知道你的用户名和电子邮箱地址。你必须提供用户名,但可使用虚构的电子邮箱地址:

$ git config —global user.name "username"
$ git config —global user.email "
username@example.com"


如果你忘记了这一步,在首次提交时Git将提示你提供这些信息。

D.2 创建项目

我们来创建一个要进行版本控制的项目。在系统中创建一个文件夹,并将其命名为git_practice。在这个文件夹中,创建一个简单的Python程序:

hello_git.py

print("Hello Git world!")


我们将使用这个程序来探索Git的基本功能。

D.3 忽略文件

扩展名为.pyc的文件是根据.py文件自动生成的,因此无须让Git跟踪它们。这些文件存储在目录pycache中。为了让Git忽略这个目录,创建一个名为.gitignore的特殊文件(这个文件名以句点打头且没有扩展名),并在其中添加下面一行内容:

.gitignore

pycache/


这让Git忽略目录pycache中的所有文件。使用文件.gitignore可避免项目混乱,让其开发起来更容易。

你可能需要修改文本编辑器的设置,使其显示隐藏的文件,这样才能使用它来打开文件.gitignore。有些编辑器被设置成忽略名称以句点打头的文件。

D.4 初始化仓库

前面创建了一个目录,其中包含一个Python文件和一个.gitignore文件,现在可以初始化一个Git仓库了。为此,打开一个终端窗口,切换到文件夹git_practice,并执行如下命令:

git_practice$ git init
Initialized empty Git repository in git_practice/.git/
git_practice$


输出表明Git在git_practice中初始化了一个空仓库。仓库 是程序中被Git主动跟踪的一组文件。Git用来管理仓库的文件都存储在隐藏的目录.git中,你根本不需要与这个目录打交道,但千万不要删除它,否则将丢失项目的所有历史记录。

D.5 检查状态

执行其他操作前,先来看一下项目的状态:

git_practice$ git status
❶ On branch master

No commits yet

❷ Untracked files:
(use "git add <file>…" to include in what will be committed)

.gitignore
hello_git.py

❸ nothing added to commit but untracked files present (use "git add" to track)
git_practice$


在Git中,分支 是项目的一个版本。从这里的输出可知,我们位于分支master 上(见❶)。你每次查看项目的状态时,输出都将指出位于分支master 上。接下来的输出表明还未执行任何提交。提交 是项目在特定时点的快照。

Git指出了项目中未被跟踪的文件(见❷),因为我们还没有告诉它要跟踪哪些文件。接下来,Git告诉我们尚未将任何东西添加到当前提交中,但指出了可能需要加入仓库中的未跟踪文件(见❸)。

D.6 将文件加入仓库中

下面将这两个文件加入仓库中,并再次检查状态:

❶ git_practice$ git add .
❷ git_practice$ git status
On branch master

No commits yet

Changes to be committed:
(use "git rm —cached <file>…" to unstage)
❸ new file: .gitignore
new file: hello_git.py

git_practice$


命令git add . 将项目中未被跟踪的所有文件都加入仓库中(见❶)。它不提交这些文件,只是让Git开始关注它们。现在检查项目的状态时,我们发现Git找出了需要提交的一些修改(见❷)。标签new file意味着这些文件是新添加到仓库中的(见❸)。

D.7 执行提交

下面来执行第一次提交:

❶ git_practice$ git commit -m "Started project."
❷ [master (root-commit) ee76419] Started project.
❸ 2 files changed, 4 insertions(+)
create mode 100644 .gitignore
create mode 100644 hello_git.py
❹ git_practice$ git status
On branch master
nothing to commit, working tree clean
git_practice$


我们执行命令git commit -m "message " (见❶)拍摄项目的快照。标志-m 让Git将接下来的消息("Started project." )记录到项目的历史记录中。输出表明位于分支master 上(见❷),且有两个文件被修改了(见❸)。

现在检查状态时,会发现我们位于分支master 上,且工作树是干净的(见❹)。这是你每次提交项目的可行状态时都希望看到的消息。如果显示的消息不是这样的,请仔细阅读,很可能是你在提交前忘记了添加文件。

D.8 查看提交历史

Git记录所有的项目提交。下面来看一下提交历史:

git_practice$ git log
commit a9d74d87f1aa3b8f5b2688cb586eac1a908cfc7f (HEAD -> master)
Author: Eric Matthes <eric@example.com>
Date: Mon Jan 21 21:24:28 2019 -0900

Started project.
git_practice$


每次提交时,Git都会生成唯一的引用ID,长40字符。它记录提交是谁执行的、提交的时间以及提交时指定的消息。并非在任何情况下都需要所有这些信息,因此Git提供了一个选项,让你能够打印提交历史条目的更简单版本:

git_practice$ git log —pretty=oneline
ee76419954379819f3f2cacafd15103ea900ecb2 (HEAD -> master) Started project.
git_practice$


标志—pretty=oneline 指定显示两项最重要的信息:提交的引用ID和为提交记录的消息。

D.9 第二次提交

为展示版本控制的强大威力,我们需要修改项目并提交所做的修改。为此,在hello_git.py中再添加一行代码:

hello_git.py

print("Hello Git world!")
print("Hello everyone.")


如果现在查看项目的状态,将发现Git注意到这个文件发生了变化:

git_practice$ git status
❶ On branch master
Changes not staged for commit:
(use "git add <file>…" to update what will be committed)
(use "git checkout — <file>…" to discard changes in working directory)

❷ modified: hello_git.py

❸ no changes added to commit (use "git add" and/or "git commit -a")
git_practice$


输出指出了当前所在的分支(见❶)和被修改了的文件的名称(见❷),还指出了所做的修改未提交(见❸)。下面来提交所做的修改,并再次查看状态:

❶ git_practice$ git commit -am "Extended greeting."
[master 51f0fe5] Extended greeting.
1 file changed, 1 insertion(+), 1 deletion(-)
❷ git_practice$ git status
On branch master
nothing to commit, working tree clean
❸ git_practice$ git log —pretty=oneline
51f0fe5884e045b91c12c5449fabf4ad0eef8e5d (HEAD -> master) Extended greeting.
ee76419954379819f3f2cacafd15103ea900ecb2 Started project.
git_practice$


我们再次执行了提交,并在执行命令git commit 时指定了标志-am (见❶)。标志-a 让Git将仓库中所有修改了的文件都加入当前提交中。(如果在两次提交之间创建了新文件,可再次执行命令git add . ,将这些新文件加入仓库中。)标志-m 让Git在提交历史中记录一条消息。

查看项目的状态时,我们发现工作树也是干净的(见❷)。最后,可以看到提交历史中包含两个提交(见❸)。

D.10 撤销修改

下面来看看如何放弃所做的修改,恢复到前一个可行状态。为此,首先在hello_git.py中再添加一行代码:

hello_git.py

print("Hello Git world!")
print("Hello everyone.")

print("Oh no, I broke the project!")


保存并运行这个文件。

我们查看状态,发现Git注意到了所做的修改:

git_practice$ git status
On branch master
Changes not staged for commit:
(use "git add <file>…" to update what will be committed)
(use "git checkout — <file>…" to discard changes in working directory)

❶ modified: hello_git.py

no changes added to commit (use "git add" and/or "git commit -a")
git_practice$


Git注意到我们修改了hello_git.py(见❶)。如果愿意,可提交所做的修改,但这次我们不提交所做的修改,而是恢复到最后一个提交(我们知道,那次提交时项目能够正常地运行)。为此,不对hello_git.py执行任何操作(不删除刚添加的代码行,也不使用文本编辑器的撤销功能),而是在终端会话中执行如下命令:

git_practice$ git checkout .
git_practice$ git status
On branch master
nothing to commit, working tree clean
git_practice$


命令git checkout 让你能够恢复到以前的任意提交。命令git checkout . 放弃最后一次提交后所做的所有修改,将项目恢复到最后一次提交的状态。

如果此时返回文本编辑器,将发现hello_git.py被修改成了下面这样:

print("Hello Git world!")
print("Hello everyone.")


就这个项目而言,恢复到前一个状态微不足道,但如果我们开发的是大型项目,其中数十个文件都被修改了,那么恢复到前一个状态,将撤销自最后一次提交后对这些文件所做的所有修改。这个功能很有用:实现新功能时,你可以根据需要做任意数量的修改,如果这些修改不可行,可撤销它们,而不会对项目有任何伤害。你无须记住做了哪些修改,因而不必手工撤销所做的修改,Git会替你完成所有这些工作。

注意  要看到以前的版本,可能需要在编辑器中刷新文件。

D.11 检出以前的提交

你可以检出提交历史中的任何提交,而不仅仅是最后一次提交,为此可在命令git check 末尾指定该提交的引用ID的前6字符(而不是句点)。通过检出以前的提交,你可以对其进行审核,然后返回到最后一次提交,或者放弃最近所做的工作并选择以前的提交:

git_practice$ git log —pretty=oneline
51f0fe5884e045b91c12c5449fabf4ad0eef8e5d (HEAD -> master) Extended greeting.
ee76419954379819f3f2cacafd15103ea900ecb2 Started project.
git_practice$ git checkout ee7641
Note: checking out 'ee7641'.

❶ You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

git checkout -b <new-branch-name>

HEAD is now at ee7641… Started project.
git_practice$


检出以前的提交后,将离开分支master ,进入Git所说的分离头指针 (detached HEAD)状态(见❶)。HEAD指针表示当前提交的项目状态,之所以说处于分离状态,是因为我们离开了一个命名分支(这里是master )。

要回到分支master ,可检出它:

git_practice$ git checkout master
Previous HEAD position was ee76419 Started project.
Switched to branch 'master'
git_practice$


这让你回到分支master 。除非要使用Git的高级功能,否则在检出以前的提交之后,最好不要对项目做任何修改。然而,如果参与项目开发的人只有你自己,而你又想放弃较近的所有提交并恢复到以前的状态,也可将项目重置到以前的提交。为此,可在处于分支master 上的情况下,执行如下命令:

❶ git_practice$ git status
On branch master
nothing to commit, working directory clean
❷ git_practice$ git log —pretty=oneline
51f0fe5884e045b91c12c5449fabf4ad0eef8e5d (HEAD -> master) Extended greeting.
ee76419954379819f3f2cacafd15103ea900ecb2 Started project.
❸ git_practice$ git reset —hard ee76419
HEAD is now at ee76419 Started project.
❹ git_practice$ git status
On branch master
nothing to commit, working directory clean
❺ git_practice$ git log —pretty=oneline
ee76419954379819f3f2cacafd15103ea900ecb2 (HEAD -> master) Started project.
git_practice$


首先查看状态,确认位于分支master 上(见❶)。查看提交历史时,我们看到了两个提交(见❷)。接下来,执行命令git reset —hard ,并在其中指定要永久恢复到的提交的引用ID前6字符(见❸)。我们再次查看状态,发现位于分支master 上,且没有需要提交的修改(见❹)。再次查看提交历史时,会发现我们回到了要重新开始的提交(见❺)。

D.12 删除仓库

有时候,仓库的历史记录被你弄乱了,而你又不知道如何恢复。在这种情况下,你首先应考虑使用附录C介绍的方法寻求帮助。如果无法恢复且参与项目开发的只有你一个人,可继续使用这些文件,但要将项目的历史记录删除——删除目录.git。这不会影响任何文件的当前状态,只会删除所有的提交,因此你将无法检出项目的其他任何状态。

为此,可打开一个文件浏览器,并将目录.git删除,也可通过命令行将其删除。这样做后,需要重新创建一个仓库,重新对修改进行跟踪。下面演示了如何在终端会话中完成这个过程:

❶ git_practice$ git status
On branch master
nothing to commit, working directory clean
❷ git_practice$ rm -rf .git
❸ git_practice$ git status
fatal: Not a git repository (or any of the parent directories): .git
❹ git_practice$ git init
Initialized empty Git repository in git_practice/.git/
❺ git_practice$ git status
On branch master

No commits yet

Untracked files:
(use "git add <file>…" to include in what will be committed)

.gitignore
hello_git.py

nothing added to commit but untracked files present (use "git add" to track)
❻ git_practice$ git add .
git_practice$ git commit -m "Starting over."
[master (root-commit) 6baf231] Starting over.
2 files changed, 4 insertions(+)
create mode 100644 .gitignore
create mode 100644 hello_git.py
❼ git_practice$ git status
On branch master
nothing to commit, working tree clean
git_practice$


首先查看状态,发现工作树是干净的(见❶)。接下来,使用命令rm -rf .git (在Windows系统中,应使用命令rmdir /s .git )删除目录.git(见❷)。删除文件夹.git后再次查看状态时,我们被告知这不是一个Git仓库(见❸)。Git用来跟踪仓库的信息都存储在文件夹.git中,因此删除该文件夹也将删除整个仓库。

接下来,使用命令git init 新建一个全新的仓库(见❹)。然后查看状态,发现又回到了初始状态,等待着第一次提交(见❺)。我们将所有文件都加入仓库,并执行第一次提交(见❻)。然后再次查看状态,发现我们位于新的分支master 上,且没有任何未提交的修改(见❼)。

你需要经过一定的练习才能学会使用版本控制,但一旦开始使用,你就再也离不开它了。

后记

祝贺你!你学习了Python基本知识,并利用这些知识创建了一些有意义的项目:创建了一款游戏,对一些数据进行了可视化,还创建了一个Web应用程序。现在,你能通过众多不同的方式进一步提高编程技能了。

首先,应该根据自己的兴趣继续开发有意义的项目。当你通过编程来解决重要的相关问题时,编程将更具吸引力,而且现在你具备了开发各种项目所需的技能。你可以开发自己的游戏,也可以开发模仿经典街机游戏的游戏。你可能想研究一些对你来说很重要的数据,并通过可视化方法将其中有趣的规律和关系展示出来。你可以创建自己的Web应用程序,也可以尝试模拟自己喜欢的应用程序。

只要有机会,就邀请别人尝试你编写的程序吧。如果你编写了游戏,就邀请别人来玩一玩;如果你创建了图表,就向别人展示展示,看看他们能否看明白;如果你创建了Web应用程序,就将其部署到在线服务器,并邀请别人尝试使用。听听用户怎么说,并努力根据他们的反馈改进项目,这样你就能成为更优秀的程序员。

自己动手开发项目时,你肯定会遇到棘手乃至无法解决的问题。请想办法寻求帮助,并加入合适的Python社区。加入当地的Python用户组,或者到一些在线Python社区逛逛就很不错。另外,考虑参加附近举办的Python开发者大会(PyCon)。

你应尽力在开发自己感兴趣的项目和提高Python技能之间取得平衡。网上有很多Python学习资料,市面上还有大量针对中级程序员编写的Python图书。现在你掌握了基本知识,并且知道了如何应用学到的技能,因此能看懂其中的很多资料。通过阅读教程和图书积累更多的知识,加深你对编程和Python的认识吧。深入学习Python后再去开发项目时,你将能够更高效地解决更多的问题。

祝贺你在学习Python的道路上走了这么远,愿你在以后的学习中有好运相伴!

作者简介

埃里克·马瑟斯(Eric Matthes)

高中科学和数学老师,现居住在阿拉斯加,在当地讲授Python入门课程。他从5岁开始就一直在编写程序。

看完了

如果您对本书内容有疑问,可发邮件至contact@turingbook.com,会有编辑或作译者协助答疑。也可访问图灵社区,参与本书讨论。

如果是有关电子书的建议或问题,请联系专用客服邮箱:ebook@turingbook.com。

在这里可以找到我们:

  • 微博 @图灵教育 : 好书、活动每日播报
  • 微博 @图灵社区 : 电子书和好文章的消息
  • 微博 @图灵新知 : 图灵教育的科普小组
  • 微信 图灵访谈 : ituring_interview,讲述码农精彩人生
  • 微信 图灵教育 : turingbooks   

091507240605ToBeReplacedWithUserId