Python 精粹(二)
原文:Lean Python
九、访问网络
Python 有标准的 1 库,使程序员能够编写使用和实现互联网服务的客户机和服务器,比如电子邮件、文件传输协议(FTP),当然还有网站。
在这一章中,我们来看看如何使用 Python 来访问网站和服务。假设您想从网站下载一个页面,并保存检索到的 HTML。用户需要输入该网站的 URL。也许您希望能够向 URL 添加一个查询字符串,以便将数据传递给请求,然后您希望显示响应或将其保存到磁盘。
当然,你应该设计你的程序分阶段工作:
-
向用户询问 URL。
-
要求将查询字符串追加到 URL。
-
询问是否保存到磁盘。
这里显示了 webtest.py 程序的列表。
1 import requests
2 from urllib.parse import urlparse
3
4 url=input('Web url to fetch:')
5 urlparts=urlparse(url)
6 if urlparts[0]=='':
7 url=''.join(('http://',url))
8
9 qstring=input('Enter query string:')
10 if len(qstring)>0:
11 url='?'.join((url,qstring))
12
13 save=input('Save downloaded page to disk [y/n]?')
14
15 print('Requesting',url)
16
17 try:
18 response = requests.get(url)
19 if save.lower()=='y':
20 geturl=response.url
21 urlparts=urlparse(geturl)
22 netloc=urlparts[1]
23 if len(netloc)==0:
24 fname='save.html'
25 else:
26 fname='.'.join((netloc,'html'))
27 print('saving to',fname,'...')
28 fp=open(fname,'w')
29 fp.write(response.text)
30 fp.close()
31 else:
32 print(response.text)
33 except Exception as e:
34 print(e.__class__.__name__,e)
让我们浏览一下这个程序。 2
-
第 1 行和第 2 行导入所需的模块(请求和 urlparse)。
-
第 4 行到第 7 行从用户那里获得一个 URL。如果用户不包括 URL 的 http://部分,程序会添加前缀。
-
第 10 到 12 行要求用户输入一个查询字符串,并用?性格。
-
第 14 行到第 16 行询问用户是否希望将输出保存到文件中,然后打印所请求的完整 URL。
-
第 18 到 40 行完成了大部分工作;任何异常都被第 34 行和第 35 行捕获。
-
第 19 行获取 URL 并保存响应。
-
第 20 到 31 行根据网站的 URL 创建一个文件名(或使用 save.html ),并将输出保存到该文件。
-
第 33 行将响应内容打印到屏幕上。
当我运行这个程序时,我看到的是:
D:\LeanPython\programs>python webtest.py
Web url to fetch:uktmf.com
Enter query string:q=node/5277
Save downloaded page to disk [y/n]?y
Requesting http://uktmf.com?q=node/5277
saving to uktmf.com.html ...
d:\LeanPython\programs>
下载页面的内容保存在 uktmf.com.html。
请求库非常灵活,因为您可以使用 requests.post()访问 HTTP“post”动词。
您可以为 post 命令提供数据,如下所示:
data = {'param1': 'value 1','param2': 'value 2'}
response = request.post(url,data=data)
在网站或 web 服务需要的地方,您可以提供用于身份验证的凭证,并以 JSON 数据的形式获取内容。您可以为请求提供定制的头,也可以很容易地看到响应中返回的头。
requests 模块可用于全面测试网站和 web 服务。
脚注
本章假设读者对 web 服务器、浏览器和 HTML 的操作有所了解。
是的,这是一个程序,第一个真正做一些你可能会发现有用的事情的程序。
十、搜索
搜索字符串
在字符串中搜索文本是一种常见的活动,内置的字符串函数 find()是简单搜索所需要的。它返回查找的位置(偏移量),如果没有找到则返回–1。
>>> txt="The quick brown fox jumps over the lazy dog"
>>> txt.find('jump')
20
>>> txt.find('z')
37
>>> txt.find('green')
-1
更复杂的搜索
通常情况下,搜索并不那么简单。我们需要寻找一种模式,从匹配的文本中提取我们真正想要的信息,而不是简单的字符串。例如,假设我们想要提取网页上链接中的所有 URL。这里有一些来自真实网页的 HTML 文本的例子。
1 <link rel="alternate" type="application/rss+xml" title="RSS: 40 newest packages" href="https://pypi.python.org/pypi?:action=packages_rss"/>
2 <link rel="stylesheet" media="screen" href="/static/styles/screen-switcher-default.css" type="text/css"/>
3 <li><a class="" href="/pypi?%3Aaction=browse">Browse packages</a></li>
4 <li><a href="http://wiki.python.org/moin/CheeseShopTutorial">PyPI Tutorial</a></li>
这篇文章中有很多内容。
-
第 1 行引用了一个 RSS 提要。
-
第 2 行有一个 href 属性,但是它引用了一个级联样式表(CSS)文件,而不是一个链接。
-
第 3 行是一个真实的链接,但 URL 是相对的;它不包含 URL 的网站部分。
-
第 4 行是到外部站点的链接。
怎么才能希望用一些软件找到自己关心的链接呢?这就是正则表达式的用武之地。
引入正则表达式 1
正则表达式 2 是一种利用模式匹配找到我们感兴趣的文本的方法。不仅模式匹配,re 模块还可以从匹配的文本中提取出我们真正想要的数据。
还可以写出更多的例子,事实上有很多关于正则表达式的书籍(例如,[16],[17])。有许多网站,但最有用的可能是 http://www . regular-expressions . info。
注意
正则表达式是包含文本和特殊字符的字符串,这些字符定义了 re 函数可以用来进行匹配的模式。
简单搜索
最简单的正则表达式是你想在另一个字符串中找到的文本字符串,如表 10-1 所示。
表 10-1。查找简单的字符串
|正则表达式
|
字符串匹配
| | --- | --- | | 跳跃 | 跳跃 | | 女王 | 女王 | | Pqr123 | Pqr123 |
使用特殊字符
表 10-2 中列出了一些特殊字符,它们会影响比赛的进行方式。
表 10-2。使用特殊字符
|标志
|
描述
|
例子
| | --- | --- | --- | | 逐字的 | 匹配文字字符串 | 跳跃 | | re1|re2 | 匹配字符串 re1 或 re2 | 是|否 | | 。 | 匹配任何单个字符(除了\n) | 国会议员 | | ^ | 匹配字符串的开头 | 这 | | | | * | 匹配前面正则表达式的 0 次或多次出现 | [阿-兹]* | | + | 匹配前面正则表达式的一次或多次出现 | [A-Z]+ | | ? | 匹配前面正则表达式的 0 次或 1 次出现 | 【a-z0-9】? | | {m,n} | 匹配前面正则表达式的 m 个和 n 个匹配项(n 可选) | [0-9]{2,4} | | [...] | 匹配字符类中的任何字符 | [aeiou] | | [x-y] | 匹配范围内的任何字符 | [0-9],[A-Za-z] | | [...] | 不匹配字符类中的任何字符 | [^aeiou] |
表 10-3 中列出了许多可以匹配的特殊字符。
表 10-3。使用特殊字符搜索
|特殊字符
|
描述
|
例子
| | --- | --- | --- | | \d | 匹配任何十进制数字 | 英国广播公司\d | | \w | 匹配任何字母数字字符 | 收音机\w+ | | \s | 匹配任何空白字符 | \sBBC |
表 10-4 给出了一些正则表达式的例子以及它们匹配的字符串。
表 10-4。正则表达式和匹配字符串
|正则表达式
|
匹配的字符串
| | --- | --- | | 史密斯|琼斯 | 琼斯·史密斯 | | 一个-什么或者说 | UN 和 O 之间的任意两个字符;例如教科文组织、联合国教科文组织、联合国教科文组织 | | 这 | 任何以 | | 结束$ | 任何以 end 结尾的字符串 | | c[阿伊]t | cat、cit、cot、cut | | [dg][io][gp] | dig,dip,dop,gig,gip,gog,gop | | [阿-德][英-意] | 2 个字符 a/b/c/d,后跟 e/f/g/h/i |
注意正则表达式可以使用文本和特殊字符的任意组合,所以它们有时看起来非常复杂。从简单开始。
在文本中查找模式
在文本中查找子字符串是没问题的,但是我们经常希望在文本中查找模式,而不是文字字符串。假设我们想从文本中提取数值、电话号码或网站 URL。我们如何做到这一点?这就是正则表达式的真正威力所在。
下面是一个正则表达式示例:
\s[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}[\s]
你能猜到它会发现什么吗?这是一个在文本中查找电子邮件地址的正则表达式。乍一看,这看起来很令人生畏,所以让我们把它分成几个组成部分。 3
这个正则表达式有六个元素:
| 1 \s2 [A-Z0-9。_%+-]+3 @4[A-Z0 9。-]+5 \.6 [A-Z]{2,4}7 [\s\] | 前导空白一个或多个字符@字符 A-Z,0-9。-点字符 2 到 4 个文本字符空白或句号 |显然,您需要知道您所搜索的模式的规则,并且有构建电子邮件地址的特定规则。
下面是文件 remail.py。
1 import re # The RegEx library
2 #
3 # our regular expression (to find e-mails)
4 # and text to search
5 #
6 regex = '\s[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}[\s]'
7 text="""This is some text with x@y.z embedded e-mails
8 that we'll use as@example.com
9 some lines have no email addresses
10 others@have.two valid email@addresses.com
11 The re module is awonderful@thing."""
12 print('** Search text ***\n'+text)
13 print('** Regex ***\n'+regex+'\n***')
14 #
15 # uppercase our text
16 utext=text.upper()
17 #
18 # perform a search (any emails found?)
19 s = re.search(regex,utext)
20 if s:
21 print('*** At least one email found "'+s.group()+'"')
22 #
23 # now, find all matches
24 #
25 m = re.findall(regex,utext)
26 if m:
27 for match in m:
28 print('Match found',match.strip())
-
第 1 行导入了我们需要的模块。
-
第 6 到 13 行定义了要搜索的文本字符串和我们将使用的正则表达式,然后打印它们。
-
第 16 行大写字母代表文本。
-
第 19 到 21 行对第一封(任何)电子邮件执行简单的搜索,并打印结果。请注意,匹配包含前导和尾随空白。
-
第 25 到 28 行查找文本中的所有匹配项并打印结果。
注意,正则表达式匹配电子邮件地址和空白边界。在第 21 行中,我们打印了包含尾随换行符的匹配,但是在第 28 行中,我们去掉了多余的字符。
当我们运行这段代码时会得到什么?这是结果。
D:\LeanPython\programs\Python3>python remail.py
** Search text ***
This is some text with x@y.z embedded emails
that we'll use as@example.com
some lines have no email addresses
others@have.two valid email@addresses.com
The re module is awonderful@thing.
** Regex ***
\s[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}[\s]
***
*** At least one email found " AS@EXAMPLE.COM
"
Match found AS@EXAMPLE.COM
Match found OTHERS@HAVE.TWO
Match found EMAIL@ADDRESSES.COM
捕捉括号
我们应该提到的另一个方面是圆括号的使用。可以像搜索任何其他字符一样搜索它们,但是也可以使用它们来描述匹配的子字符串,re 模块可以捕获这些子字符串,并将它们放在搜索过程返回的列表中。在下面的例子中,这些所谓的捕捉括号提供了我们想要从 HTML 页面中提取的 URL。
在 HTML 中查找链接
以下程序使用 urlliblibrary 下载单个网页。然后使用复杂的正则表达式搜索下载的 HTML 内容的文本,该表达式提取文本链接并提供 URL 和用户看到的链接文本。
这个程序叫做 regex.py。
1 import urllib.request
2 import re # The RegEx library
3 #
4 # this code opens a connection to the leanpy.com website
5 #
6 response = urllib.request.urlopen('http://leanpy.com')
7 data1 = str(response.read()) # put response text in data
8 #
9 # our regular expression (to find links)
10 #
11 regex = '<a\s[^>]*href\s*=\s*\"([^\"]*)\"[^>]*>(.*?)</a>'
12 #
13 # compile the regex and perform the match (find all)
14 #
15 pm = re.compile(regex)
16 matches = pm.findall(data1)
17 #
18 # matches is a list
19 # m[0] - the url of the link
20 # m[1] - text associated with the link
21 #
22 for m in matches:
23 ms=''.join(('Link: "',m[0],'" Text: "',m[1],'"'))
24 print(ms)
此处显示了该程序的输出。
1 D:\LeanPython\programs>python re.py
2 200 OK
3 Link: "http://leanpy.com/" Text: "Lean Python "
4 Link: "#content" Text: "Skip to content"
5 Link: "http://leanpy.com/" Text: "Home"
6 Link: "http://leanpy.com/?page_id=33" Text: "About Lean Python "
7 Link: "http://leanpy.com/" Text: "<img src="http://leanpy.com/wp-content/uploads/2014/04/cropped-LeanPythonHeader.jpg" class="header-image" width="950" height="247" alt="" />"
8 Link: "http://leanpy.com/?p=1" Text: "The Lean Python Pocketbook"
9 Link: "http://leanpy.com/?p=1#respond" Text: "<span class="leave-reply">Leave a reply</span>"
10 Link: "http://leanpy.com/wp-content/uploads/2014/04/OnePieceCover1-e1396444631642.jpg" Text: "<img class="wp-image-17 alignleft" alt="OnePieceCover" src="http://leanpy.com/wp-content/uploads/2014/04/OnePieceCover1-e1396444631642-633x1024.jpg" width="305" height="491" />"
11 Link: "http://leanpy.com/?cat=3" Text: "Lean Python Book"
12 Link: "http://leanpy.com/?tag=book" Text: "Book"
13 Link: "http://leanpy.com/?p=1" Text: "<time class="entry-date" datetime="2014-04-02T12:06:06+00:00">April 2, 2014</time>"
14 Link: "http://leanpy.com/?author=1" Text: "paulg"
15 Link: "http://leanpy.com/?p=1" Text: "The Lean Python Pocketbook"
16 Link: "http://leanpy.com/?cat=3" Text: "Lean Python Book"
17 Link: "http://leanpy.com/wp-login.php?action=register" Text: "Register"
18 Link: "http://leanpy.com/wp-login.php" Text: "Log in"
19 Link: "http://leanpy.com/?feed=rss2" Text: "Entries <abbr title="Really Simple Syndication">RSS</abbr>"
20 Link: "http://leanpy.com/?feed=comments-rss2" Text: "Comments <abbr title="Really Simple Syndication">RSS</abbr>"
21 Link: "http://wordpress.org/" Text: "WordPress.org"
22 Link: "http://wordpress.org/" Text: "Proudly powered by WordPress"
你可以看到程序识别了所有的链接,但是还没有我们希望的那么智能。
-
*第 4 行:*这个链接使用了同一个页面的书签。
-
*第 7 行:*链接文本实际上是一个图像(我们需要担心这个吗?).
作为练习,也许您可以改进所使用的正则表达式。
脚注
Python re 模块的完整文档可以在 docs.python.org/3/library/r… 的 ?? 找到。正则表达式是任何编程语言中的高级主题。
2 通常,正则表达式简称为 regex。
请注意,这个电子邮件查找器 regex 并不完美。它不会在字符串的开头找到地址,并且会忽略尾部元素中超过四个字符的电子邮件地址(例如。手机)。
十一、数据库
每个 1 应用都使用某种形式的(持久)存储。我们已经看过纯文本文件了。在这一章中,我们考虑 Python 程序如何访问和使用数据库,尤其是关系数据库。
Python 提供了访问所有流行数据库的标准函数。有许多开源和商业数据库产品,每个都有自己的适配器,允许 Python 连接和使用其中保存的数据。出于我们的目的,我们使用 SQLite 数据库,因为它不需要安装其他软件。
数据库
SQLite 是一个非常轻量级的无服务器工具。核心 Python 产品包括 SQLite 适配器,允许我们演示最重要的数据库特性。SQLite 的行为方式与大型系统相同,但是管理开销很低(接近于零)。这样做的结果是 SQLite 可以用于开发或原型制作,以后可以迁移到更复杂的数据库。出于我们的目的,SQLite 提供了我们需要的所有特性。
数据库功能
这些是我们将使用的关键 SQLite 数据库函数:
# open (or create) a database file and return
# the connection
conn = sqlite3 .connect(filename)
# executes a SQL statement
conn.executescript(sql)
# return a cursor
cursor = conn.cursor()
# execute the SQL query that returns rows of data
cursor.execute(sql)
# returns the data as a list of rows
rows = cursor.fetchall()
将数据连接并加载到 SQLite 中
下面是一个示例程序,它创建一个新的数据库,一个单独的表,插入一些数据,执行一个查询,并尝试插入一个重复的行(dbcreate.py)。
1 import os
2 import sqlite3
3
4 db_filename='mydatabase.db'
5 #
6 # if DB exists - delete it
7 #
8 exists = os.path.exists(db_filename)
9 if exists:
10 os.unlink(db_filename)
11 #
12 # connect to DB (create it if it doesn't exist)
13 #
14 conn = sqlite3.connect(db_filename)
15 #
16 # create a table
17 #
18 schema="""create table person (
19 id integer primary key autoincrement not null,
20 name text not null,
21 dob date,
22 nationality text,
23 gender text)
24 """
25 conn.executescript(schema)
26 #
27 # create some data
28 #
29 people="""insert into person (name, dob,nationality,gender)
30 values ('Fred Bloggs', '1965-12-25','British','Male');
31 insert into person (name, dob,nationality,gender)
32 values ('Santa Claus', '968-01-01','Lap','Male');
33 insert into person (name, dob,nationality,gender)
34 values ('Tooth Fairy', '1931-03-31','American','Female');
35 """
36 conn.executescript(people)
37 #
38 # execute a query
39 #
40 cursor = conn.cursor()
41 cursor.execute("select id, name, dob,nationality,gender from person")
42 for row in cursor.fetchall():
43 id, name, dob,nationality,gender = row
44 print("%3d %15s %12s %10s %6s" % (id, name, dob,nationality,gender))
45 #
46 # attempt to insert a person with no name
47 #
48 try:
49 dupe="insert into person (id, dob,nationality,gender) \
50 values (1,'1931-03-31','American','Female');"
51 conn.executescript(dupe)
52 except Exception as e:
53 print('Cannot insert record',e.__class__.__name__)
-
第 1 行和第 2 行导入了我们需要的模块。
-
第 4 行到第 10 行删除一个旧的数据库文件(注意不要将在这个程序中创建的数据库用于任何有用的用途!).
-
第 14 行创建数据库文件。
-
在第 18 到 25 行,模式是一组命令(一个 SQL 脚本),它将创建一个新表。
-
第 26 行执行 SQL 脚本来创建新表。
-
在第 29 到 36 行中,定义了一个新的脚本,其中包含在新表中插入三条记录的 SQL 命令。
-
第 37 行执行脚本。
-
在第 40 到 44 行,要执行一个查询,您需要创建一个游标,然后使用该游标执行查询。这将建立查询内容,但不会获取数据。cursor.fetchall()提供了一个可迭代的行列表,这些行被分配给命名变量,然后打印出来。
-
第 48 行到第 53 行建立了一个行的插入,try…except 子句捕获插入中的错误。insert SQL 故意省略了 name 字段来触发异常。
这个程序的输出显示为 hee。
D:\LeanPython\programs>python dbcreate.py
1 Fred Bloggs 1965-12-25 British Male
2 Santa Claus 968-01-01 Lap Male
3 Tooth Fairy 1931-03-31 American Female
Cannot insert record IntegrityError
第 52 行的 insert 语句导致的异常被触发,因为没有提供 name 字段(并且必须不为 null)。
在下面的清单(dbupdate.py)中,我们向程序传递两个参数,并在 SQL update 命令中使用它们来更改一个人的国籍。
1 import sqlite3
2 import sys
3 #
4 # arguments from command line
5 # use: python dbupdate.py 1 Chinese
6 #
7 db_filename = 'mydatabase.db'
8 inid = sys.argv[1]
9 innat = sys.argv[2]
10 #
11 # execute update using command-line arguments
12 #
13 conn = sqlite3.connect(db_filename)
14 cursor = conn.cursor()
15 query = "update person set nationality = :nat where id = :id"
16 cursor.execute(query, {'id':inid, 'nat':innat})
17 #
18 # list the persons to see changes
19 #
20 cursor.execute("select id, name, dob,nationality,gender from person")
21 for row in cursor.fetchall():
22 id, name, dob,nationality,gender = row
23 print("%3d %15s %12s %10s %6s" % (id, name, dob,nationality,gender))
-
第 8 行和第 9 行从命令行获取数据:inid 和 innat。
-
第 13 行到第 16 行完成了大部分工作。第 13 和 14 行设置了光标。第 15 行和以前一样是 SQL,但是用于 SQL 中的字段(id 和 nat)的值是使用冒号符号(:id 和:nat)参数化的。第 16 行执行查询,并使用字典作为调用{'id':inid,' nat':innat}的第二个参数来提供参数的实际值。
这里显示了输出。
D:\LeanPython\programs>python dbupdate.py 1 Chinese
1 Fred Bloggs 1965-12-25 Chinese Male
2 Santa Claus 968-01-01 Lap Male
3 Tooth Fairy 1931-03-31 American Female
冒号符号和字典可用于参数化任何 SQL 调用。
脚注
本章假定您了解关系数据库模型和简单结构化查询语言(SQL)命令。
十二、接下来呢?
在这本小书中,我介绍了我在自己的 Python 开发中使用的核心 Python 特性。如果您完成了所有的示例,使用交互式解释器进行了实验,并且使用了示例程序,那么您将会很好地掌握这种出色的编程语言的最基本的元素。
不过,Python 的其他方面可能看起来相当神秘。关于正则表达式、web 应用和 SQLite 的章节只是为了激起您学习更多内容的兴趣。
如果你像我一样,有编程缺陷,将没有什么能阻止你探索这门语言,以及你能用它做什么。如果你是一个使用另一种语言的有经验的程序员,我希望你能理解 Python 是如何工作的,以及编写代码的容易程度。您甚至可能会考虑放弃您的旧语言,转而使用 Python。你们中的一些人可能已经看够了。编程、Python 和所有那些废话可能不适合你。你以前怀疑过,至少现在你确定了。
如果你选择更进一步,这里有一些建议:
-
1.购买一本好的语言参考书,或者熟悉附录中给出的在线 Python 参考资料。
-
2.探索 PyPI 资源。无论你想用代码做什么,别人已经创建了一个库,这将使你的生活变得更加容易。利用这一点。
-
3.练习。就这么简单。就像口语和许多其他技能一样,如果你不使用它,你就会失去它。如果本周你不用 Python 来工作,那就用它来娱乐吧。
如果你用 Python 走得更远,我知道你会玩得很开心!
附录
参考
网页 1
-
1.
www.artima.com/intv/pythonP.html。访 Python 的发明者吉多·范·罗苏姆。 -
2.
en . Wikipedia . org/wiki/Python _(programming _ language。Python 语言的维基百科条目。 -
3.
web2py.com。Web2py web 开发框架。 -
4.
legacy.python.org/dev/peps/pep-0008/。Python 代码的(PEP 8)风格指南。 -
5.
legacy.python.org/dev/peps/pep-0020/。Python 的禅。 -
6.
wiki.python.org/moin/Python2orPython3。我应该用 Python 2 还是 Python 3? -
7.
pypi . python . org/pypi。Python 软件包索引。 -
8.
docs.python.org/3/using/cmdline.html。使用 Python 命令行环境。 -
9.
www.python.org。Python 语言的官方网站。 -
10.
docs.python.org/。Python 标准文档。 -
11.
docs.python.org/3/library/index.html。Python 标准库。 -
12.
legacy.python.org/dev/peps/pep-0020/。Python 的禅(2014)。
书
-
13.*核心 Python 编程,*卫斯理·淳。
-
14.Python 标准库举例, Doug Hellmann。
-
15.Alex Martelli,David Ascher 和 Anna Martelli Ravenscroft。
-
16.*掌握 Python 正则表达式,*菲利克斯·洛佩兹和维克多·罗梅罗。
-
17.*掌握正则表达式,*杰弗里·弗里德尔。
工具
-
18.视觉塞斯尔:
www.obelisk.me.uk/cesil/(2016)。 -
19.PIP 安装程序:
www . pip-installer . org/(2014 年)。 -
20.Python 单元测试框架:
docs.python.org/3.4/library/unittest.html。
Python 内置的异常层次 2
在第七章中,我们描述了 Python 如何管理异常。我们在那里介绍了一些异常类型,但这里是完整的列表。
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
| +-- BufferError
| +-- ArithmeticError
| | +-- FloatingPointError
| | +-- OverflowError
| | +-- ZeroDivisionError
| +-- AssertionError
| +-- AttributeError
| +-- EnvironmentError
| | +-- IOError
| | +-- OSError
| | +-- WindowsError (Windows)
| | +-- VMSError (VMS)
| +-- EOFError
| +-- ImportError
| +-- LookupError
| | +-- IndexError
| | +-- KeyError
| +-- MemoryError
| +-- NameError
| | +-- UnboundLocalError
| +-- ReferenceError
| +-- RuntimeError
| | +-- NotImplementedError
| +-- SyntaxError
| | +-- IndentationError
| | +-- TabError
| +-- SystemError
| +-- TypeError
| +-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
脚注
1 这些 URL 在发布时有效,但可能会发生变化。