序言
欢迎学习 Google 的 Python 在线教程。它基于内部提供的入门级 Python 课程。如设置页面中所述,本资料介绍了 Python 3。
如果您想学习相应的 MOOC 课程,可以试试 Udacity 和 Coursera 提供的课程(编程入门[初学者]或 Python 入门)。最后,如果您希望不观看视频,而是以自定进度在线学习,请尝试这篇文章末尾列出的资源。其中每个资源都包含学习内容以及可供您练习的 Python 交互式解释器。我们提到的“解释器”是什么?您将在下一部分中找到答案!
语言简介
Python 是一种动态解释型(字节码编译型)语言。源代码中没有变量、参数、函数或方法的类型声明。这样可以使代码简短灵活,但您将无法对源代码进行编译时类型检查。Python 在运行时会跟踪所有值的类型,并标记运行时没有意义的代码。
如需了解 Python 代码的运作方式,一个绝佳的方法是运行 Python 解释器,然后直接在其中输入代码。如果您遇到过类似“如果我将 int
添加到 list
会发生什么情况?”这样的问题,只需将其输入到 Python 解释器中即可快速完成,而且可能是查看结果的最佳方式。(请参阅下文,了解实际情况!)
$ python3 ## Run the Python interpreter Python 3.X.X (XXX, XXX XX XXXX, XX:XX:XX) [XXX] on XXX Type "help", "copyright", "credits" or "license" for more information. >>> a = 6 ## set a variable in this interpreter session >>> a ## entering an expression prints its value 6 >>> a + 2 8 >>> a = 'hi' ## 'a' can hold a string just as well >>> a 'hi' >>> len(a) ## call the len() function on a string 2 >>> a + len(a) ## try something that doesn't work Traceback (most recent call last): File "", line 1, in TypeError: can only concatenate str (not "int") to str >>> a + str(len(a)) ## probably what you really wanted 'hi2' >>> foo ## try something else that doesn't work Traceback (most recent call last): File " ", line 1, in NameError: name 'foo' is not defined >>> ^D ## type CTRL-d to exit (CTRL-z in Windows/DOS terminal)
在您输入 python 并在 >>> 提示之前,Python 会输出两行内容,告知您所使用的 Python 版本及其构建位置。只要输出的第一个内容是“Python 3”,这些示例应该适合您。
如上所示,您可以轻松地对变量和运算符进行实验。此外,如果代码尝试读取未分配值的变量,解释器会抛出(在 Python 术语中称为“引发”)运行时错误。与 C++ 和 Java 一样,Python 区分大小写,因此“a”和“A”是不同的变量。行末标记了语句的结束,因此与 C++ 和 Java 不同,Python 不需要在每条语句的末尾添加分号。注释以“#”开头,并持续到这一行的结束。
Python 源代码
Python 源文件使用“.py”扩展名,称为“模块”。对于 Python 模块 hello.py
,运行它的最简单方法是使用 shell 命令“python hello.py Alice”,该命令会调用 Python 解释器来执行 hello.py
中的代码,并将命令行参数“Alice”传递给它。如需了解从命令行运行 Python 时可用的所有不同选项,请参阅官方文档页面。
下面是一个非常简单的 hello.py
程序(请注意,代码块是严格使用缩进而不是大括号进行分隔的,我们稍后会详细介绍!):
#!/usr/bin/python3 # import modules used here -- sys is a very standard one import sys # Gather our code in a main() function def main(): print('Hello there', sys.argv[1]) # Command line args are in sys.argv[1], sys.argv[2] ... # sys.argv[0] is the script name itself and can be ignored # Standard boilerplate to call the main() function to begin # the program. if __name__ == '__main__': main()
从命令行运行此程序的如下所示:
$ python3 hello.py Guido Hello there Guido $ ./hello.py Alice ## without needing 'python3' first (Unix) Hello there Alice
导入、命令行参数和 len()
Python 文件(或“模块”)中的最外层语句会执行一次性设置 - 这些语句会在模块首次被导入某个位置时从上到下运行,从而设置其变量和函数。Python 模块可以直接运行(如上文中的 python3 hello.py Bob
),也可以被其他模块导入并使用。直接运行 Python 文件时,特殊变量“__name__”会设置为“__main__”。因此,在直接运行模块时(而不是在模块由其他模块导入时),上面所示的样板 if __name__ ==...
会调用 main() 函数,这种情况很常见。
在标准 Python 程序中,列表 sys.argv
以标准方式包含命令行参数,其中 sys.argv[0] 是程序本身,sys.argv[1] 是第一个参数,依此类推。如果您了解 argc
或参数数量,只需使用 len(sys.argv)
从 Python 请求此值,就像我们在上面的交互式解释器代码中请求字符串的长度时一样。通常,len()
可以告诉您字符串的长度、列表和元组(另一种类似数组的数据结构)中的元素数量,以及字典中键值对的数量。
用户定义的函数
Python 中的函数定义如下:
# Defines a "repeat" function that takes 2 arguments. def repeat(s, exclaim): """ Returns the string 's' repeated 3 times. If exclaim is true, add exclamation marks. """ result = s + s + s # can also use "s * 3" which is faster (Why?) if exclaim: result = result + '!!!' return result
另请注意,构成函数或 if 语句的行是如何按照所有具有相同缩进级别的规则分组的。我们还介绍了重复字符串的 2 种不同方法,一种是使用更易于用户使用的 + 运算符,但 * 运算符也可以,因为它是 Python 的“重复”运算符,这意味着 '-' * 10
会产生 '----------'
,这是一种在屏幕上创建“线条”的简洁方法。在代码注释中,我们暗示 * 的运行速度比 + 快,原因是 * 只会计算一次生成对象的大小,而 + 则会在每次调用时进行计算。+ 和 * 都称为“重载”运算符,因为它们对数字和字符串(以及其他数据类型)的含义不同。
def
关键字用于定义函数及其参数(参数位于圆括号内),并使代码缩进。函数的第一行可以是文档字符串(“docstring”),用于描述函数的用途。docstring 可以是单行,也可以是多行说明(如上例所示)。(没错,这些都是“三引号”,这是 Python 独有的功能!)在函数中定义的变量是该函数的局部变量,因此上述函数中的“result”与另一个函数中的“result”变量是相互独立的。return
语句可以接受参数,在这种情况下,该参数就是返回给调用方的值。
以下代码会调用上述 repeat() 函数,并输出其返回的内容:
def main(): print(repeat('Yay', False)) ## YayYayYay print(repeat('Woo Hoo', True)) ## Woo HooWoo HooWoo Hoo!!!
在运行时,必须先通过执行“def”来定义函数,然后才能调用函数。通常,我们会在文件底部定义 main() 函数,并在其上方定义它调用的函数。
缩进
Python 的一个不寻常的特性是,一段代码的空白缩进会影响其含义。语句的逻辑块(例如构成函数的语句)应具有相同的缩进,从其父函数或“if”或其他语句的缩进设置。如果某个组中的某行采用了不同的缩进,系统会将其标记为语法错误。
刚开始,Python 对空白的使用感觉有点奇怪,但它很符合逻辑,我发现自己很快就适应了。避免使用 TAB,因为这会大大使缩进方案变得非常复杂(更不用说 TAB 在不同平台上的含义可能不同)。将您的编辑器设置为在 Python 代码中插入空格而不是 TAB。
初学者常常会问“我应该缩进多少个空格?”根据 Python 官方编程风格指南 (PEP 8),您应使用 4 个空格进行缩进。(趣味知识:Google 的内部样式指南规定要缩进 2 个空格!)
在运行时检查的代码
Python 在编译时几乎不进行任何检查,而是将每行代码的几乎所有类型、名称等检查推迟到该行代码运行时。假设上述 main() 调用 repeat() 如下所示:
def main(): if name == 'Guido': print(repeeeet(name) + '!!!') else: print(repeat(name))
if 语句包含一个明显的错误,其中 repeat() 函数被意外输入为 repeeeet()。Python 中有一个有趣的现象:只要运行时的名称不是“Guido”,此代码就可以正常编译和运行。只有当运行作业实际尝试执行 repeeeet() 时,才会注意到没有此类函数并引发错误。此代码段中还有第二个错误。在与“Guido”进行比较之前,未为 name 分配值。如果尝试对未分配的变量求值,Python 将引发“NameError”。以下示例展示了,当您首次运行 Python 程序时,您会看到一些简单的拼写错误或未初始化的变量等错误。在这一方面,具有更详细类型系统的语言(例如 Java)具有优势,因为它们可以在编译时捕获此类错误(但当然,您必须维护所有这些类型信息,这是一种权衡)。
Python 3 引入了类型提示。借助类型提示,您可以指明函数中每个参数的类型以及函数返回的对象的类型。例如,在带有注解的函数 def is_positive(n: int) -> bool:
中,参数 n
为 int
,返回值为 bool
。我们稍后会介绍这些类型的含义。不过,类型提示完全是可选的。您会发现越来越多的代码采用类型提示,因为如果您使用类型提示,一些编辑器(例如 cider-v 和 VS.code)可以运行检查,以验证是否使用正确的参数类型调用了函数。它们甚至可以在您编辑代码时建议和验证参数。
本教程不会介绍类型提示,但我们希望确保您在听到或在实际使用中看到类型提示时能够了解它们。
变量名称
由于 Python 变量在源代码中没有明确的类型,因此为变量命名有助于提醒您正在发生的情况。因此,如果是单个名称,请使用“name”;如果是名称列表,请使用“names”;如果是元组列表,请使用“tuples”。许多基本 Python 错误都是因为忘记每个变量中的值类型而导致的,因此请使用变量名称(您实际上拥有的所有信息)来帮助您理清思路。
就实际命名而言,有些语言更倾向于使用下划线_部分来表示由“多个字词”组成的变量名称,但有些语言更倾向于使用驼峰式命名法。通常,Python 更倾向于使用下划线方法,但如果要集成到已使用该样式的现有 Python 代码中,则建议开发者改用驼峰式命名法。可读性很重要。如需了解详情,请参阅 PEP 8 中的命名惯例部分。
如您所知,诸如“if”和“while”之类的关键字不能用作变量名称,否则会出现语法错误。不过,请注意不要将内置函数用作变量名称。例如,虽然“str”“list”和“print”看似不错,但您将覆盖这些系统变量。内置函数不是关键字,因此很容易被新手 Python 开发者无意中使用。
关于模块及其命名空间的更多信息
假设您有一个模块“binky.py”,其中包含“def foo()”。该 foo 函数的完全限定名称为“binky.foo”。这样,各种 Python 模块可以随意为其函数和变量命名,并且变量名称不会冲突 - module1.foo 不同于 module2.foo。在 Python 词汇表中,我们可以说 binky、module1 和 module2 都有自己的“命名空间”,您可以猜到,这是变量名称到对象的绑定。
例如,我们有一个标准的“sys”模块,其中包含一些标准系统工具,如 argv 列表和 exit() 函数。然后,您可以使用“import sys”语句访问 sys 模块中的定义,并通过其完全限定名称(例如 sys.exit())使其可用!(是的,“sys”也有命名空间!)
import sys # Now can refer to sys.xxx facilities sys.exit(0)
还有一种导入表单,如下所示:“from sys import argv, exit”。这样,您就可以使用短名称调用 argv 和 exit();不过,我们建议使用包含完全限定名称的原始形式,因为这样更容易确定函数或属性的来源。
许多模块和软件包都与标准安装的 Python 解释器捆绑在一起,因此您无需执行任何额外的操作即可使用它们。这些库统称为“Python 标准库”。常用的模块/软件包包括:
- sys - 访问 exit()、argv、stdin、stdout 等
- re - 正则表达式
- os - 操作系统接口、文件系统
您可以在 http://docs.python.org/library 上找到所有标准库模块和软件包的文档。
在线帮助、help()
和dir()
您可以通过多种方式获取 Python 帮助。
- 在 Google 上进行搜索,以单词“python”开头,例如“python list”或“python string strings”。第一个命中结果通常就是答案。出于某种原因,这种技术似乎更适用于 Python 而非其他语言。
- Python 官方文档网站 docs.python.org 提供了优质文档。不过,我发现通过 Google 搜索几个字词往往更快。
- 此外,我们还专门为刚开始学习 Python 和/或编程的用户提供了官方导师邮寄名单!
- 您可以在 StackOverflow 和 Quora 上找到许多问题(和答案)。
- 使用 help() 和 dir() 函数(见下文)。
在 Python 解释器中,help() 函数会调出各种模块、函数和方法的文档字符串。这些文档字符串类似于 Java 的 javadoc。dir() 函数会告诉您对象的属性是什么。以下是从解释器调用 help() 和 dir() 的一些方法:
help(len)
- 内置len()
函数的帮助字符串;请注意,它是“len”而不是“len()”,它是对函数的调用,我们并不希望这样help(sys)
-sys
模块的帮助字符串(必须先执行import sys
)dir(sys)
-dir()
与help()
类似,但只会快速列出其定义的符号(即“属性”)help(sys.exit)
-sys
模块中exit()
函数的帮助字符串help('xyz'.split)
- 字符串对象的split()
方法的帮助字符串。您可以使用该对象本身或该对象的示例以及其属性调用help()
。例如,调用help('xyz'.split)
与调用help(str.split)
相同。help(list)
-list
对象的帮助字符串dir(list)
- 显示list
对象属性,包括其方法help(list.append)
-list
对象的append()
方法的帮助字符串