原文:https://developers.google.com/edu/python/introduction
欢迎来到 Google 的 Python 在线教程。本教程最初是在 Python 2.4 期间创建的,我们也尝试保持通用的内容和有价值的练习。这几篇文章覆盖了 Python 2。虽然我们现在“不讨论”Python 3,但是要意识到它将是未来,未来很多新的功能都会出现在 Python 3 中。好消息是开发者在学习完某一个版本之后,再学习其它版本就不会太难了。如果你想知道更多关于在 Python 2 和 Python 3 之间如何选择的内容,那么请查看这篇文章。
Python 是一种动态的、解释型(bytecode-compiled)语言。在源码里面,没有对变量、参数、函数或者方法的类型声明。这使得代码简短而灵活,但是也失去了在编译时对源码的类型检查。Python 在运行时追踪所有值的类型并且标示出那些在运行时不合理的代码。
一个很好的查看 Python 代码工作情况的方法是运行解释器并将代码输入进去。如果你有类似这样的问题:“如果我添加了一个 int
到一个 list
会发什么?”最快和貌似是最好的查看结果的方法是直接将代码输入到 Python 解释器。(查看下面的例子来发现结果是啥!)
$ python ## Run the Python interpreter
Python 2.7.9 (default, Dec 30 2014, 03:41:42)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-55)] on linux2
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: cannot concatenate 'str' and 'int' objects
>>> 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 用语抛出或者“显示”一个运行时的错误。像 C++ 和 Java 一样,Python 是大小写敏感的,所以 “a” 和 “A” 是不同的变量。一行的结束标示着一个语句的结束,所以不像 C++ 和 Java,Python 不需要在每个语句末尾加上一个分号。以 ‘#’ 开始到该行的末尾是注释。
Python 源文件使用 “.py” 扩展名。这些文件称作”模块(modules)“。对于一个 Python 模块 hello.py
,运行它最简单的方法是使用 shell 命令 “python hello.py Alice”。该命令调用 Python 解释器来执行 hello.py
里面的代码,并且将命令行参数 “Alice” 传进去。请打开官方文档了解当从命令行运行 Python 时,所有的选项。
下面是一个很简单的 hello.py
程序(注意这里使用缩进而不是花括号严格地将代码块分隔开来——后面会有更多关于这方面的内容!):
#!/usr/bin/env python
# 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()
像下面一样在命令行下运行上述程序:
$ python hello.py Guido
Hello there Guido
$ ./hello.py Alice ## without needing 'python' first (Unix)
Hello there Alice
在 Python 文件或者“模块”最外面的语句,对文件做一次性设置——模块第一次被导入到其它地方时,那些语句会从文件的上到下运行,在这个过程中设置变量和函数。一个 Python 模块可以直接运行——如前面介绍的 “python hello.py Bob”——或者也可以导入到别的模块,被别的模块使用。当直接运行一个 Python 文件,特殊的变量”__name__“会被设为”__main__“。因此,当直接运行模块时,通常会有样板 if __name__ ==...
来调用 main() 函数,但是当模块导入到其它模块时就不适用了。
在一个标准的 Python 程序中,列表 sys.argv
用标准的方式包含了命令行参数。sys.argv[0] 代表程序自身,sys.argv[1] 表示第一个参数,以此类推。如果你知道 argc
或者参数的数量,那么可以像我们在之前介绍的交互式解释器做的一样,你可以简单地通过 len(sys.argv)
从 Python 得到这个值。通常来说,len()
可以输出一个字符串的长度,列表(list)或者元组(tuple)(另一种类数组的数据结构)中元素的数量,和字典(dictionary)中键-值对的数量。
在 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”)。docstring 可以是单独一行,也可以像上述例子中的多行描述。(没错,那些是“三引号”,Python 特有的特性!)定义在函数内的变量在函数中是局部的,所以上面函数的 “result” 与其它函数的 “result” 变量是不一样的。在值返回给一个调用函数的情况下,return
语句可以带参数。
下面是调用上述 repeat() 函数的代码,打印该函数的返回值:
def main():
print repeat('Yay', False) ## YayYayYay
print repeat('Woo Hoo', True) ## Woo HooWoo HooWoo Hoo!!!
在运行时,函数必须在被调用之前就用 “def” 定义好。通常将 main() 函数放在文件的底部, main() 调用的函数放在它上面。
Python 一个不常见的特点是一个代码块的空格缩进影响着它的意义。像组成一个函数的逻辑语句块应该拥有相同的缩进,以他们的父函数或者 “if” 或者其它开始的缩进开始。如果同一组代码中有一行的缩进与其它行不同,Python 会提示语法错误。
刚开始会觉得 Python 使用的空格有点怪怪的,但是它是有逻辑的并且我发现我很快就适应了空格的用法。避免使用 TAB,因为 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()。有趣的是,只要在运行时 name 不是 ‘Guido’ ,这个代码可以编译和运行成功。只有当在运行时尝试执行 repeeeet() 时,Python 才会提示没有这个函数并且提示错误。这只是想表达当你首次运行一个 Python 程序时,一些错误会像这样简单的拼写错误。这是其它带有更多详细信息的语言,如 Java,的一个优势。这些语言可以在编译的时候捕捉到错误(但是当然你需要维护所有类型信息。这是一个权衡)。
由于 Python 变量的类型不需要在源码中写出来,为变量命名一个有意义的名字显得特别重要,这可以提醒你自己发生了什么。所以如果是单个名字,使用 “name”,如果是一列名字,使用 “names”,如果是一列元组,使用 “tuples”。很多基本的错误时由于忘记了每个变量的值的类型导致的,所以使用变量名来帮助记忆。
至于实际命名方面,一些语言会使用下划线将“多个单词”组成一个变量名,另一些语言则会使用骆驼命名法来命名变量。通常,Python 推荐使用下划线的方法,但是如果需要整合的 Python 代码使用的是骆驼命名法来命名的,此时我们会引导开发者使用骆驼命名法。更多的内容请阅读PEP 8 的命名习惯章节。
如你所想,像 ‘print’ 和 ‘while’ 这些关键字不可以用作变量名——如果这样做会得到一个语法错误。无论如何,请小心不要使用内置的单词来做变量名。例如,’str’ 和 ‘list’ 看起来像是好的名字,但是这样的话会重写那些系统变量。内置的单词并不是关键字,所以 Python 的开发新手很容易会因为疏忽而使用。
假设你有一个模块 “blink.py”,里面包含一个 “def foo()”。那个 foo 函数的全名是 “binky.foo”。这样,不同的 Python 模块可以将函数和变量命名成他们想要的,并且变量名不会冲突——module1.foo 与 module2.foo 是不同的两个函数。在 Python 词汇里,我们可以说 binky,module1 和 module2 有自身的“命名空间”,即变量名与对象(name-to-object)的绑定。
例如,标准的 “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 —— 操作系统接口,文件系统
你可以在 https://docs.python.org/2/library/ 中找到所有的标准库模块和包。
有很多方法可以获得关于 Python 的帮助。
在 Google 中,以单词 “Python” 开头进行搜索,如 “python list” 或者 “python string lowercase”。第一条结果通常就是答案。这个方法貌似对于 Python 比对于其它语言效果要好。
官方的 Python 文档——https://docs.python.org——有一些高质量的文档。尽管如此,我发现用 Google 更快。
官方的邮件列表是为那些刚接触 Python 或者编程的人专门设计的。
很多问题(和答案)可以在 StackOverflow 和 Quora 中找到。
使用 help() 和 dir() 函数(请看下面的内容)。
在 Python 解释器里面,help() 函数会列出不同模块、函数和方法的文档字符串。这些文档字符串类似于 Java 的 javadoc。dir() 函数会告诉我们一个对象的属性是什么。下面是从解释器调用 help() 和 dir() 的一些方法:
help(len)
——内置 len()
函数的帮助字符串;注意到这里是 “len” 不是 “len()”。”len()” 是对一个函数的调用,而在这里我们并不是要调用函数。
help(sys)
——sys
模块的帮助字符串(在之前必须先 import sys
)。
dir(sys)
——dir()
类似于 help()
,但是 dir()
只给出一个 sys
定义的符号或者“属性”的快捷列表。
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()
方法的帮助字符串。