β

Python 官方教程学习

Home 64 阅读

Python 是容易学习且强大的的编程语言,具有高级数据结构和简单但高效的面向对象特点。 The Python Tutorial 是官方的教程,现在我想深入学习 Python 语言,我觉得 如果想了解它的细节和思想一个好的学习方法就是认真的去阅读官方的文档和源码。所以接 下来计划我会对 Python 官方的文档进行详细的阅读并且做一些必要的笔记。分别阅读的是:

  1. The Python Tutorial (Python 教程)
  2. The Python Language Reference (Python 语言参考)
  3. The Python Standard Library (Python 标准库)

阅读顺序也按照上面的依次学习。本篇是 The Python Tutorial,会持续更新,完成本文。

Table of Contents

Whetting Your Appetite (激发你的学习欲望)

本小节大致介绍 Python 的优点来激发你的学习欲望,说着学习 Python 你的开发周期更短, 并且跨平台使用,即可以做脚本语言来使用同样也可以编写庞大的程序,还可以嵌入到更高级的 语言当中做为其扩展中的一部分来增加它的动态特性。总得来说简单易用集各种优点的高级动态 语言值得去学习和使用,就是那名话:“人生苦短,我用 Python ” 。

Using the Python Interpreter (使用 Python 解释器)

Invoking the Interpreter (调用解释器)

调用解释器在 Unix*上直接在命令行里输入 Python 就可以打开,如果是 Windows 的话可能 需要增加环境变量,如 set path=%path%;C:\python27 。退出的话直接按 Control-D 或者在解释器输入退出指令: quit()或 exit()

Python 的第二种启动解释器的方法是 Python -c command [arg] ... ,将执行 command 中语句,如 python -c "import sys; print sys.path" 。Python 也可以使用某一个模块,如: python -m SimpleHTTPServer

The Interpreter and Its Environment (解释器及它的环境)

Error Handling (错误处理)

当发生错误里,解释器打印出错误消息和跟综信息,如果从一个文件输入,程序会退出返回 一个非零值状态并打印 stack trace。

Executable Python Scripts (执行脚本)

Python 可以执行脚本,在文件开头的第一行输入:

#! /usr/bin/env python

使用 chmod 命令给于执行权限就可以当程序一个来执行一个脚本:

$ chmod +x myscript.py

如果是 windows 的话,系统会根据后缀为 .py 或.pyw 来自动执行 python.exe 来解释。

Source Code Encoding (源代码编码方式)

在 python 源代码可能使用不同的编码方式,最好的方法是在源文件中加入声明编码方式,格式为 # -*- coding: encoding -*- ,声明为 UTF-8 的编码方式如下:

# -*- coding: UTF-8 -*-

查看详细的编码列表可以在 Python Library Reference 的 codecs 章节找到。

The Interactive Startup File (解释器交互模式的启动配置文件)

在使用 Python 解释器里,可以配置 Python 交互模式的启动配置文件,类似于 shell 里的 .profile ,Python 的启动配置文件使用 PYTHONSTARTUP 环境变量来设置,配置文件 仅仅对启动 python 解释器的交互模式会话时起作用,执行脚本或其它不会执行启动配置文件。 如果执行脚本使用启动配置文件需要额外的技巧,如:

import os
filename = os.environ.get('PYTHONSTARTUP')
if filename and os.path.isfile(filename):
    execfile(filename)

An Informal Introduction to Python (非正式的 Python 简介)

在接下来的实例中,输入和输出是通过区分存在或不存在的提示(>>>...), 在 Python 中注释是以 # 开始的行,例如:

# this is the first comment
SPAM = 1                 # and this is the second comment
                         # ... and now a third!
STRING = "# This is not a comment."

Using Python as a Calculator (使用 python 当作计算器)

Numbers (数值)

解释器可以扮演一个简单的计算器,它可以输入表达式并将计算结果返回,表达式语法是明确且简单 的操作符 + - * / 使用起来像其它语言一个(比如 Pascal 或 C),圆括号的优先级也一样。

>>> 2+2

>>> # This is a comment
... 2+2

>>> 2+2  # and a comment on the same line as code

>>> (50-5*6)/4

>>> # Integer division returns the floor:
... 7/3

>>> 7/-3
-3

等号 = 作用是给一个变量赋值

>>> width = 20
>>> height = 5*9
>>> width * height

一个值也可以同时给多个变量赋值

>>> x = y = z = 0  # Zero x, y and z
>>> x

>>> y

>>> z

变量在使用之前必须定义,否则将会发出错误:

>>> # try to access an undefined variable
... n
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'n' is not defined

全面支持浮点型,计算通过混合的类型运算,整形运算会被转换成浮点型

>>> 3 * 3.75 / 1.5
.5
>>> 7.0 / 2
.5

同样复数也支持,虚数表示以后缀为 j 或 J 。非零复数实部写成(实部+虚部 (real+imagj) 或者使用 complex(real,imag) 创建。

>>> 1j * 1J
(-1+0j)
>>> 1j * complex(0,1)
(-1+0j)
>>> 3+1j*3
(3+3j)
>>> (3+1j)*3
(9+3j)
>>> (1+2j)/(1+1j)
(1.5+0.5j)

复数通常由实部和虚部组组成,分别提取实部和虚部可以使用 z.real 或 z.imag 来表示。

>>> a=1.5+0.5j
>>> a.real
.5
>>> a.imag
.5

从复数进行数值转换到浮点型或整型时会出错,没有正确的方法转换一个复数到实数,使用 abc(z) 来获取它的数值或 z.real 来得到它的实部。

>>> a=3.0+4.0j
>>> float(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: can't convert complex to float; use abs(z)
>>> a.real
.0
>>> a.imag
.0
>>> abs(a)  # sqrt(a.real**2 + a.imag**2)
.0

在解释器交互模式里,最后打印的表达式被赋予变量 _ 。意味着当使用 Python 当做一个桌面 计算器时,可以根据上一次结果断续计算。另外,=_= 变量为只读属性,不能赋值给它。

>>> tax = 12.5 / 100
>>> price = 100.50
>>> price * tax
.5625
>>> price + _
.0625
>>> round(_, 2)
.06
Strings (字符串)

除了数值外,Python 也可以操作字符串,可以多种表达方法。字符串可以使用单引号或双引号。

>>> 'spam eggs'
'spam eggs'
>>> 'doesn\'t'
"doesn't"
>>> "doesn't"
"doesn't"
>>> '"Yes," he said.'
'"Yes," he said.'
>>> "\"Yes,\" he said."
'"Yes," he said.'
>>> '"Isn\'t," she said.'
'"Isn\'t," she said.'

字符串有多种方法可以分隔多行的表示方式。在行的最后一个字符使用反斜杠表示逻辑继续。

hello = "This is a rather long string containing\n\
several lines of text just as you would do in C.\n\
    Note that whitespace at the beginning of the line is\
 significant."

print hello

This is a rather long string containing
several lines of text just as you would do in C.
    Note that whitespace at the beginning of the line is significant.

字符串可以一对三单引号或三双引号围绕来表示多行文字输出。使用三单或双引号在行的最后一个 字符不使用反斜杠,一切在引号中都表示变通字符来打印。

print """
    Usage: thingy [OPTIONS]
         -h                        Display this usage message
         -H hostname               Hostname to connect to
    """
输出:
    Usage: thingy [OPTIONS]
         -h                        Display this usage message
         -H hostname               Hostname to connect to

如果我们需要字符串的原始表示,即 \n 也不转换,但反斜杠在行末。

hello = r"This is a rather long string containing\n\
    several lines of text much as you would do in C."

    print hello

输出:

    This is a rather long string containing\n\
    several lines of text much as you would do in C.

字符串可以使用 + 作为连接符,* 作为重复次数。

>>> word = 'Help' + 'A'
>>> word
'HelpA'
>>> '<' + word*5 + '>'
'<HelpAHelpAHelpAHelpAHelpA>'

当两个字符串连接可以也可以使用 word = 'Help' 'A' ,但不包括任意的字符串表达式。

>>> 'str' 'ing'                   #  <-  This is ok
'string'
>>> 'str'.strip() + 'ing'   #  <-  This is ok
'string'
>>> 'str'.strip() 'ing'     #  <-  This is invalid
  File "<stdin>", line 1, in ?
    'str'.strip() 'ing'
                      ^
SyntaxError: invalid syntax

字符串可以索引,像 C 语言一样在一串字符串中第一个字符的下标为 0。没有分隔字符类型, 一个字符是一个简单的字符串大小。像图标,子字符串可以通过切片来表示,通过冒号两个 标引分隔。

>>> word[4]
'A'
>>> word[0:2]
'He'
>>> word[2:4]
'lp'

默认切片分隔非常有用,省略的第一个索引默认为 0,省略的第二个索引默认为字符串的大小。

>>> word[:2]    # The first two characters
'He'
>>> word[2:]    # Everything except the first two characters
'lpA'

和 C 语言不一样,Python 里字符串不可以改变。赋予一个字符给索引位置结果会发出错误:

>>> word[0] = 'x'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: object does not support item assignment
>>> word[:1] = 'Splat'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: object does not support slice assignment

使用联结创建新的字符串是非常容易且高效的。

>>> 'x' + word[1:]
'xelpA'
>>> 'Splat' + word[4]
'SplatA'

s[:i] + s[i:] 等于 s 是非常有用的切片操作。

>>> word[:2] + word[2:]
'HelpA'
>>> word[:3] + word[3:]
'HelpA'

向后切片索引处理有时候非常优美。一个索引太大来替换字符的大小,上限小于下限将返回空 字符串。(Degenerate slice indices are handled gracefully: an index that is too large is replaced by the string size, an upper bound smaller than the lower bound returns an empty string.)

>>> word[1:100]
'elpA'
>>> word[10:]
''
>>> word[2:1]
''

如果计数从右开始,索引的下标为负数。

>>> word[-1]     # The last character
'A'
>>> word[-2]     # The last-but-one character
'p'
>>> word[-2:]    # The last two characters
'pA'
>>> word[:-2]    # Everything except the last two characters
'Hel'

需要注意的是 -0 的索引值和 0 是一样的,-0 它不会从右索引起。

>>> word[-0]     # (since -0 equals 0)
'H'

超出范围的负切片会被截断,但在单个切片而不是范围时超出的话会引发出错。

>>> word[-100:]
'HelpA'
>>> word[-10]    # error
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
IndexError: string index out of range

记住切片如何工作的一个方法是想像切片为字符间的位置,左边第一个字符为 0,右边最后一个字符 为字符串中的 n 个字符有 n 个索引,例如: 内部函数 len()返回字符串的长度:

>>> s = 'supercalifragilisticexpialidocious'
>>> len(s)

进一步查看支持大多数字符串的方法,格式化,序列类型等。

  • Sequence Types – str, unicode, list, tuple, bytearray, buffer, xrange
  • String Methods
  • String Formatting
  • String Formatting Operations
Unicode Strings (Unicode 字符串编码)

从 Python2.0 开始 Unicode 字符编码作为一种新的数据类型存储文本数据。可以使用它来保存 和操作 Unicode 数据。unicode 有许多优点。

Python 里创建 Unicode 字符串像创建平常的字符串一样简单:

>>> u'Hello World !'
u'Hello World !'

创建在单引号前 u 表示字符串支持 unicode。也可以 u 的字符串里插入 unicode 的特殊 编码字符。

>>> u'Hello\u0020World !'
u'Hello World !'

可以在 u 加上 r 结合来输入带 unicode 原始字串。输入原始字串有时候在正则表达式时非常有用。

>>> ur'Hello\u0020World !'
u'Hello World !'
>>> ur'Hello\\u0020World !'
u'Hello\\\\u0020World !'

内建函数 unicode()提供访问到全部的 unicode 编码。

The built-in function see unicode(). provides access to all registered Unicode codecs (COders and DECoders). Some of the more well known encodings which these codecs can convert are Latin-1, ASCII, UTF-8, and UTF-16. The latter two are variable-length encodings that store each Unicode character in one or more bytes. The default encoding is normally set to ASCII, which passes through characters in the range 0 to 127 and rejects any other characters with an error. When a Unicode string is printed, written to a file, or converted with see str(), conversion takes place using this default encoding.

>>> u"abc"
u'abc'
>>> str(u"abc")
'abc'
>>> u"äöü"
u'\xe4\xf6\xfc'
>>> str(u"äöü")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)

To convert a Unicode string into an 8-bit string using a specific encoding, Unicode objects provide an encode() method that takes one argument, the name of the encoding. Lowercase names for encodings are preferred.

>>> u"äöü".encode('utf-8')
'\xc3\xa4\xc3\xb6\xc3\xbc'

If you have data in a specific encoding and want to produce a corresponding Unicode string from it, you can use the *note unicode(). function with the encoding name as the second argument.

>>> unicode('\xc3\xa4\xc3\xb6\xc3\xbc', 'utf-8')
u'\xe4\xf6\xfc'
Lists (列表)

Python 支持很多复合数据类型,用来组合其它的值。最常用的就是列表 list 。 可以用方括号包括数据来表示,列表的条目的数据类型可以不一样。

>>> a = ['spam', 'eggs', 100, 1234]
>>> a
['spam', 'eggs', 100, 1234]

列表可以像字符串一样支持切片操作,索引从 0 开始,列表支持索引,连接等等

>>> a[0]
'spam'
>>> a[3]

>>> a[-2]

>>> a[1:-1]
['eggs', 100]
>>> a[:2] + ['bacon', 2*2]
['spam', 'eggs', 'bacon', 4]
>>> 3*a[:3] + ['Boo!']
['spam', 'eggs', 100, 'spam', 'eggs', 100, 'spam', 'eggs', 100, 'Boo!']

全部的切片操作返回一个包括新元素的新列表。意味着下面的切片返回 a 列表的一个复本。

>>> a[:]
['spam', 'eggs', 100, 1234]

不同于字符串的不可变,在列表里元素是可以改变的,并且这是常常使用的。

>>> a
['spam', 'eggs', 100, 1234]
>>> a[2] = a[2] + 23
>>> a
['spam', 'eggs', 123, 1234]

列表的赋值操作非常灵活,可以改变列表的大小或者清空列表等

>>> # Replace some items:
... a[0:2] = [1, 12]
>>> a
[1, 12, 123, 1234]
>>> # Remove some:
... a[0:2] = []
>>> a
[123, 1234]
>>> # Insert some:
... a[1:1] = ['bletch', 'xyzzy']
>>> a
[123, 'bletch', 'xyzzy', 1234]
>>> # Insert (a copy of) itself at the beginning
>>> a[:0] = a
>>> a
[123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]
>>> # Clear the list: replace all items with an empty list
>>> a[:] = []
>>> a
[]

内建的 len()函数也可以用于求列表的大小

>>> a = ['a', 'b', 'c', 'd']
>>> len(a)

列表也可以嵌套

>>> q = [2, 3]
>>> p = [1, q, 4]
>>> len(p)

>>> p[1]
[2, 3]
>>> p[1][0]

>>> p[1].append('xtra')     # See section 5.1
>>> p
[1, [2, 3, 'xtra'], 4]
>>> q
[2, 3, 'xtra']

上面的例子 p[1]q 指向同一个对象。

First Steps Towards Programming

举一个实例,写一个初始人子序列斐波那契数列如下:

>>> # Fibonacci series:
... # the sum of two elements defines the next
... a, b = 0, 1
>>> while b < 10:
...     print b
...     a, b = b, a+b
...





上面的例子介绍许多特性

  • 第一行为一复合赋值语句,a 和 b 分别赋予 0 和 1 值。
  • while 循环,Python 像 C 语言一样非 0 整数值为真,0 为假。这里的条件也可以是字符串或是列表的值,

实际上包括任何序列;任何非 0 长度为真,空序列为假。在例子里测试使用一个简单 的比较关系。标准的关系比较操作符像 C 语言一样: < 小于, > 大于, == 等于, <= 小于等于, >= 大于等于, != 不等于。

  • 循环体里缩进,缩进在 Python 里表示为语句块。
  • print 语句打印数值

More Control Flow Tools (深入流程控制)

除了前面介绍的 while 语句,Python 支持同其它语言一样的控制语句,但也有些不同。

if Statements (if 判断语句)

可能最为常见的语句就是 if 语句

>>> x = int(raw_input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
...      x = 0
...      print 'Negative changed to zero'
... elif x == 0:
...      print 'Zero'
... elif x == 1:
...      print 'Single'
... else:
...      print 'More'
...
More

for Statements (for 循环语句)

for 语句使用与其它 C 或者 Pascal 语言有点不同,Python 的 for 语句迭代通过任何序列 条目,例如:

>>> # Measure some strings:
... a = ['cat', 'window', 'defenestrate']
>>> for x in a:
...     print x, len(x)
...
cat 3
window 6
defenestrate 12

通过循环迭代修改序列是不安全的(这种只能使用 mutable sequence types,例如列表)。 通过迭代如果需要修改列表(例如复制选择的条目),你必须通过迭代复制,这种方法使这 尤其方便。

>>> for x in a[:]: # make a slice copy of the entire list
...    if len(x) > 6: a.insert(0, x)
...
>>> a
['defenestrate', 'cat', 'window', 'defenestrate']

The range() Function: The range Function. (range 函数)

如果需要通过一序列的数字来迭代,内建函数 range() 就很便利。它生成列表包括算术处理:

>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

The given end point is never part of the generated list; range(10) generates a list of 10 values, the legal indices for items of a sequence of length 10. It is possible to let the range start at another number, or to specify a different increment (even negative; sometimes this is called the 'step'):

>>> range(5, 10)
[5, 6, 7, 8, 9]
>>> range(0, 10, 3)
[0, 3, 6, 9]
>>> range(-10, -100, -30)
[-10, -40, -70]

To iterate over the indices of a sequence, you can combine see range() and see len(). as follows:

>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
...     print i, a[i]
...
 Mary
 had
 a
 little
 lamb

In most such cases, however, it is convenient to use the see enumerate(). function, see Looping Techniques

break and continue Statements, and else Clauses on Loops (break, continue 语句以及 else 在循环里)

break 语句像 C 语言一样跳出(break out)for 和 while 循环。

continue 语句也同 C 语言一样继续下一个循环的迭代。

Loop statements may have an `else' clause; it is executed when the loop terminates through exhaustion of the list (with see for.) or when the condition becomes false (with see while.), but not when the loop is terminated by a see break. statement. This is exemplified by the following loop, which searches for prime numbers(搜索 素数):

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print n, 'equals', x, '*', n/x
...             break
...     else:
...         # loop fell through without finding a factor
...         print n, 'is a prime number'
...
 is a prime number
 is a prime number
 equals 2 * 2
 is a prime number
 equals 2 * 3
 is a prime number
 equals 2 * 4
 equals 3 * 3

pass Statements (pass 语句)

pass 语句不作任何事情,它可以用在当一个语句语法上是必须但程序不作任何事。如

>>> while True:
...     pass  # Busy-wait for keyboard interrupt (Ctrl+C)
...

这是常用来创建最小的类:

>>> class MyEmptyClass:
...     pass
...

另一个地方使用 pass 语句可能就是 TODO 的作用。如

>>> def initlog(*args):
...     pass   # Remember to implement this!
...

Defining Functions (函数定义)

我们可以创建一个函数以一个任意边界求斐波那契数列:

>>> def fib(n):    # write Fibonacci series up to n
...     """Print a Fibonacci series up to n."""
...     a, b = 0, 1
...     while a < n:
...         print a,
...         a, b = b, a+b
...
>>> # Now call the function we just defined:
... fib(2000)
 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

关键字 def ,表示一个函数定义,后面必须跟函数名和圆括号内的形参。函数体开始语句的下一行 ,并且必须为缩进。

函数体的第一条语句可以为可选的字符串常量,字符串常量做为函数的文档说明(更多关于文档注释可是 Documentation Strings 章节查看),在代码里包含文档字符是好的做法,所以养成好的习惯。

一个函数的 execution 介绍新的符号表用于函数的本地变量。恰恰的,在函数里的全部变量赋值的值保存 在本地符号表里。而变量引用首先在局部符号表查找,然后在 enclosing function 的局部符号表, 然后在全局符号表里,最后才在内置的符号表里。因此,全局变量不能通过一个函数直接赋值(除非关键词 global 语句),虽然它们可能被引用到。

More on Defining Functions (更详细的函数定义)

Intermezzo; Coding Style (代码风格)

Data Structures

Modules

Input and Output

Errors and Exceptions

Classes

Brief Tour of the Standard Library

Brief Tour of the Standard Library – Part II

What Now?

Interactive Input Editing and History Substitution

Floating Point Arithmetic; Issues and Limitations

作者:Home
原文地址:Python 官方教程学习, 感谢原作者分享。

发表评论