Python 简介

序言

欢迎参加 Google 的 Python 在线教程。它基于内部提供的 Python 入门课程。如设置页面中所述,本材料涵盖 Python 3。

如果您想寻找配套的 MOOC 课程,不妨试试 Udacity 和 Coursera 上的课程(编程入门 [初学者] 或 Python 入门)。最后,如果您想观看视频,而是自定进度地在线学习,请尝试这篇博文末尾列出的资源 - 每个资源都包含学习内容以及可供您练习的 Python 交互式解释器。我们提到的“翻译器”是什么?您将在下一部分中找到答案!

语言简介

Python 是一种动态的解释型(字节码编译)语言。源代码中没有变量、形参、函数或方法的类型声明。这会使代码变得简短而灵活,但您会失去源代码的编译时类型检查。Python 会在运行时跟踪所有值的类型,并在运行时标记不合理的代码。

了解 Python 代码运作方式的一个绝佳方法是运行 Python 解释器,然后直接在其中输入代码。如果您有任何疑问,例如“如果我向 list 添加 int 会发生什么?”,只需将其输入到 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] 是第一个实参,依此类推。如果您知道 argv 或实参的数量,只需使用 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 语句的行是如何通过具有相同的缩进级别进行分组的。我们还介绍了两种不同的字符串重复方式:一种是使用更易于使用的 + 运算符,另一种是使用 * 运算符,因为它是 Python 的“重复”运算符,这意味着 '-' * 10 会生成 '----------',这是一种在屏幕上创建“线条”的简洁方式。在代码注释中,我们提示 * 的运行速度比 + 快,原因是 * 只计算一次结果对象的大小,而 + 每次被调用时都会进行计算。之所以说 + 和 * 都是“重载”运算符,是因为它们对于数字和字符串(以及其他数据类型)的含义不同。

def 关键字用于定义函数,其参数位于圆括号内,代码则采用缩进格式。函数的第一行可以是用于描述函数功能的文档字符串(简称“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 对空格的使用起初感觉有点奇怪,但它很合理,我很快就习惯了。避免使用制表符,因为它们会大大增加缩进方案的复杂性(更不用说制表符在不同平台上的含义可能不同)。将编辑器设置为插入空格而不是制表符作为 Python 代码的缩进。

初学者常问的一个问题是:“应该缩进多少个空格?”根据 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() 时,它才会注意到没有这样的函数并引发错误。此代码段中还存在第二个错误;在将 name 与“Guido”进行比较之前,未为 name 分配值。如果您尝试评估未分配的变量,Python 将引发“NameError”。以下是一些示例,它们表明,首次运行 Python 程序时,您看到的一些最先出现的错误将是简单的拼写错误或未初始化的变量,如这些示例所示。在这一方面,Java 等类型系统更详细的语言具有优势,因为它们可以在编译时捕获此类错误(但当然,您必须维护所有这些类型信息,这是一种权衡)。

Python 3 引入了类型提示。 类型提示可让您指明函数中每个实参的类型,以及函数返回的对象的类型。例如,在带注释的函数 def is_positive(n: int) -> bool: 中,实参 nint,返回值是 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 lowercase”。第一个搜索结果通常就是答案。出于某种原因,此技术似乎更适合 Python,而不是其他语言。
  • 官方 Python 文档网站 (docs.python.org) 提供了高质量的文档。不过,我经常发现,在 Google 上搜索几个字词会更快。
  • 此外,我们还提供专门为 Python 和/或编程新手设计的官方 Tutor 邮寄名单
  • 您可以在 StackOverflowQuora 上找到许多问题(和答案)。
  • 使用 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() 方法的帮助字符串