学习Python¶
目录:
概述¶
注解
学习 Python 不要将时间浪费在记 API 的功能上,而应该学习 Python 的编程理念。
对于重要模块 os, sys,应该尽量熟悉模块里的方法和属性;
对于常用的 API,应该熟悉使用方法;记不住也没关系,重要的是要学会使用 Python Manuals
。
os 和 sys 模块¶
sys 模块与 Python 解析器相关:
sys.path
列举了 Python 解析器真正的搜索路径。 当模块被载入时,Python 从左到右依次获取
sys.path
中的目录。 每获取一个目录,就遍历目录中的文件,直至找到和模块名相同的文件名为止。
sys.path
在 Python 解析器运行的时候初始化。 Python 加载环境变量PYTHONPATH
的值,作为 sys.path 的初始值。 当然sys.path
的值不都是来自于PYTHONPATH
,它的值是可以修改的。警告
对
sys.path
的修改维持到 Python 解析器退出访问
sys.path
可以使用os.getcwd()
函数。
sys.modules
列举已经加载的模块。 这是一个字典结构
sys.exec_info()
发生异常时,可以通过这个接口获取异常类型,值以及回溯对象。
- 标准输入输出流
标准流包括:
sys.stdin
sys.stdout
sys.stderr
sys.argv
获取命令行参数
os 模块与 Python 解析器运行的操作系统有关:
环境变量 os.environ 运行程序工具 os.system 创建进程 os.fork 描述文件和锁 os.open 文件处理 os.remove, os.rename 管理工具 os.getcwd 跨平台工具 os.path os.sep 路径名工具 os.path
脚本中运行命令行¶
os 模块提供了工具,可以在 Python 脚本中执行命令行。
函数名 功能 os.system 在 Python 脚本中执行命令行 os.popen 执行命令行并连接输入输出流
另外, 模块 subprocess
对命令行中流的控制比上面两个函数更全面。
与命令行的“通信”¶
os.system()
只是简单地运行命令行;os.popen()
连接命令的标准输入或者输出流。
默认情况下,获取一个类文件对象,连接命令行的输出(如果用 'w'
标志,则是命令行的输入)。
通过该对象,可以读取命令行产生的输出。
1 2 | os.popen('type 1.txt').read()
os.popen('type 2.txt').readlines()
|
程序使用方式¶
每个 Python 模块都有一个属性变量 __name__
。
当 Python 将模块当做程序运行时,模块的 __name__
的值为 __main__
;
当模块作为库文件加载时,__name__
的值不再是 __main__
。
脚本上下文¶
“Python scripts do not run in a vacuum.”
Python 不是运行在真空中。
当前工作目录¶
CWD
——Current Working Directory
当前工作目录是一个十分重要的概念,是脚本处理的文件默认“呆”的地方,除非脚本中的文件名是绝对路径。
前一章提到,os.getcwd()
获取 CWD
的名称,os.chdir()
允许脚本将 CWD
转移到新的路径。
记住,不带完整路径的文件名会自动映射到 CWD
中,和 PYTHONPATH
没有关系。
从技术实现上看,脚本总是从 CWD
中启动的,而不是脚本所在的目录。
与此相反的是,import
脚本总是包含脚本的目录开始,不是 CWD
(除非脚本恰好也处在 CWD
下)。
在命令行窗口运行 Python 脚本:

CWD
的值是 C:
。
打印系统搜索路径的前6项(os.path[0:6]
)会发现 D:
也在其中。
这说明 Python 会自动将脚本的根目录添加到系统搜索路径中。
这样的话,无论在哪运行脚本,该脚本都可以直接加载相同目录下的其它文件。
假定 test.py
在 D:
目录下,则可以直接加载:
import test
希尔环境变量¶
os.environ
存储所有环境变量获取环境变量
os.environ
是一个 Python 的字典,因而可以通过键名访问对应的键值。例如,设置系统环境变量
PYTHONPATH
之后,运行 Python 解析器,就会将PYTHONPATH
自动加载到os.environ
中。 可以通过os.environ["PYTHONPATH"]
语句来访问。修改环境变量
由于
os.environ
是一个字典,因而可以通过赋值的方式来修改环境变量。注意
父进程修改的环境变量可以被子进程继承。 反之,子进程修改的环境变量对于父进程是不可见的。
典型的例子:在命令窗口中执行脚本,命令窗口程序是父进程,通过
set
修改的环境变量可以被脚本程序继承。 而脚本程序中的环境变量的修改不会在命令窗口中体现出来。Python 产生子进程的方法有:
- os.popen
- subprocess.popen
- os.system
- os.fork
- os.spawnv
- os.fork, etc.
标准流¶
1 2 3 | sys.stdout.write('hello,world\n') # print('hello,world')
sys.stdin.readline() # in = input()
# print in
|
- 标准输入流的数据默认来自于键盘输入
- 标准输出流默认将输出文本打印到控制台窗口
- 标准错误流默认将错误信息打印到控制台窗口
流重定向¶
为什么要引入流重定向呢? 最直接的应用是 Python 脚本进行白盒测试:提供输入,测试输出信息。 要截获输出到控制台的文本信息,必须用到流重定向。
在 Windows 命令窗口中这种重定向比较简单,使用 >/>>
命令可以很方便地将文本信息输出到某个文件中。例如:
1 2 3 | echo hello,world > 1.txt ; 从 1.txt 开头进行覆盖
echo hello,world >> 1.txt ; 从 1.txt 结尾追加
python input_name.py < 1.txt ; 将 1.txt 的内容给脚本 input_name.py 的标准输入流
|
如果想将输出信息传递给另一个命令行,或者程序,可以使用管道指令 |
:
1 2 3 4 | # 1.py
import sys
print sys.argv[1]
|
在命令窗口中执行指令:echo hello,world | python 1.py
,打印结果为 hello,world
。
流重定向到 Python对象¶
前面的流重定向都依赖于命令行,本节将介绍将流直接重定向到 Python 文件对象的方法。
Python 有一个很有意思的思想:
“If it looks like a duck and quacks like a duck, it must be a duck.”
长得像鸭子,叫得像鸭子,肯定是鸭子。
提供文件方法的对象都可以作为标准流:
- 带
read()
方法的对象可以赋值给 sys.stdin;read()
为输入流提供数据 - 带
write()
方法的对象可以赋值给 sys.stdout; 所有标准输出都发给write()
方法。
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Input(object):
def read(self):
return 'hello, world\n'
class Output(object):
def write(self, s):
f = open('1.txt', 'w')
f.write(s)
f.close()
sys.stdin = Input()
sys.stdin.read() # 'hello, world'
sys.stderr = Input()
sys.stderr.read() # 'hello, world'
sys.stdout = Output()
sys.stdout.write('hello, world\n') #生成文件 1.txt,输入文本 'hello, world\n'
|
print()
的重定向¶
Python模块¶
目录:
subprocess模块¶
subprocess.Popen
¶
注解
类
构造函数常用参数:
args
字符串或者参数序列。shell=False
是否打开命令窗口执行命令行stdin=None
可以取PIPE
,文件句柄,文件描述符和None
stdout=None
可以取PIPE
,文件句柄,文件描述符和None
stderr=None
可以取PIPE
,文件句柄,文件描述符,STDOUT
和None
重要
流对象为 None
时,子进程将继承父进程的标准流。
1 2 3 4 5 6 7 8 9 10 11 12 13 | #D:\hello_world.py
print hello,world
#D:\test_subprocess.py
from subprocess import *
# ``shell = True`` cannot be skipped, as it uses shell to run the command line
open_obj = Popen('hello_world.py', shell = True, stdout = PIPE)
# If you want to ignore ``shell`` parameter, you can use executable parameter as below:
# open_obj = Popen('python hello_world.py', stdout = PIPE)
out_obj = open_obj.communicate()
print open_obj[0]
|
Popen
实例¶
poll()
子进程是否结束,返回returncode
属性值wait()
等待子进程结束,返回returncode
属性值警告
构造
Popen
对象时,不要使用PIPE
参数,会死锁。communicate()
阻塞式执行命令行,返回元组(stdoudata, stderrdata)
。注解
要返回元组
(stdoudata, stderrdata)
,实例化时,必须设置stdout=PIPE
; 要想将数据传递给子进程的输入流,必须设置stdin=PIPE
。send_signal()
发信号给子进程(SIGTERM
)terminate()
终止子进程kill()
杀死子进程
注解
Windows 中 kill()/terminate()
一样,都是调用 Windows API:TerminateProcess
;
Unix 中 terminate()
发送消息 SIGTERM
, kill()
发送消息 SIGKILL
pid
表示子进程的 ID;如果使用shell=True
,则表示命令窗进程的 IDreturncode
None
表示子进程未结束;Unix 中,-N
表示等待信号N
结束子进程。stdout
如果实例化时,设置stdout=PIPE
,则stdout
为子进程的输出流;否则为None
stderr
如果实例化时,设置stderr=PIPE
,则stderr
为子进程的错误流;否则为None
stdin
如果实例化时,设置stdin=PIPE
,则stdin
为子进程的输入流;否则为None
1 2 | open_obj = Popen('python hello_world.py', stdout=PIPE)
print open_obj.stdout.read()
|
subprocess
的便捷接口¶
call()
阻塞式执行命令行,返回returncode
属性值警告
不能设置参数 stdout=PIPE/stderr=PIPE,会死锁
check_call()
阻塞式执行命令行,返回0,表示子进程正常退出; 否则抛出异常CalledProcessError
check_output()
阻塞式执行命令行,正常情况下返回命令行输出(字节数组); 否则抛出异常CalledProcessError
注解
不能使用
stdout=PIPE
,可以使用stderr=STDOUT
来捕获并输出错误信息。
URL访问的扩展库—— urllib2
¶
urllib2
主要用于基础和摘要式的身份验证,网页跳转,网页 cookie 等等。
urllib2.urlopen(url, [,data][,timeout])
url
字符串 /
Request
对象。警告
HTTPS 请求不进行服务器认证
data
取值为字符串或者
None
,定义传递给服务器的用户数据。重要
目前为止,HTTP 请求是唯一用到
data
参数的用户请求;data
不为None
时,HTTP 请求为POST
方式。data
必须符合application/x-www-form-urlencoded
格式规范。 例如:name='hwz'®ion='beijing'
可以调用函数
urllib.urlencode()
做数据格式转换:1 2 3 4 5
import urllib dic = {"name":"hwz", "region":"beijing"} encoded_data = urllib.urlencode(dic) print encoded_data # 'region=beijing&name=hwz'
urllib.urlencode()
的输入参数为字典或者二元组序列,返回的是application/x-www-form-urlencoded
格式的字符串。 urllib2 模块支持 HTTP/1.1 版本的请求,请求头中带有 Connection:close 键值。timeout
指定连接超时时间(s),等待连接是阻塞式的; 若没有指定,使用的是全局默认的数值。
重要
该参数仅对 HTTP, HTTPS 和 FTP 连接起作用。
返回值
返回一个仿文件对象,指向的是服务器的响应消息。
注解
服务器的 HTTP 响应消息,包括响应头(元信息)和响应体(也就是数据资源)。 响应体可以是
text/html
文档,也就是浏览器中的网页的源代码; 也可以是图片资源,还可以是二进制的数据,或者application/json
字符串等等。返回对象除了常规文件读写方法之外,还提供两个额外的方法:
geturl()
获取服务器返回的资源对应的 URL;URL 指含有该资源的网址; 比如网页资源,则返回该网页的 URL:
1 2
response = urllib2.open('http://www.baidu.com') print response.geturl() # 'http://www.baidu.com'
info()
返回服务器响应的元信息,比如响应头信息。 其格式是
mimetools.Message
。可以通过键名获取响应头信息,比如:
1 2 3
response = urllib2.open('http://www.baidu.com') meta_data = response.info() print meta_data.getheaders('Content-Type') # ['text/html; charset=utg-8']
异常
URLError
urllib2.install_opener(opener)
手动安装全局访问器。
重要
系统默认安装的全局访问器,使用
UnknownHandler
请求处理器; 如果设置了*_proxy
环境变量(例如set http_proxy=*
),全局访问器使用的ProxyHandler
。用
<OpenerDirector instance>.open()
代替urlopen()
,可以不用安装全局访问器。urllib2.build_opener([handler,...])
返回一个访问器对象。
访问器内部设置了请求处理器列表,可以通过
handler,...
手动设置处理列表。handler,...
是BaseHandler
的实例/不带参数的子类。以下请求处理器将自动排在
handler,...
前面(出现在handler,...
中的除外):ProxyHandler
UnknownHandler
HttpHandler
HttpDefaultErrorHandler
HttpRedircetHandler
FTPHandler
FileHandler
HTTPErrorProcessor
如果安装 Python 的时候支持 SSL(即可以加载
ssl
模块),还会加入HTTPSHandler
。urllib2.Request(url, [data][,headers][,origin_req_host][,unverifiable])
注解
请求类
url
URL 字符串。
data
与
urllib2.urlopen()
的data
参数说明一致headers
headers
是一个字典。对于
headers
的处理,相当于调用add_header()
; 表示给请求头添加新的键值对,比如指定User-Agent
键值对。注解
服务器可以利用
User-Agent
字段过滤请求。 例如,Mozilla 火狐浏览器的User-Agent
为Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 FireFox/2.0.0.11
; 而urllib2
的User-Agent
默认为Python-urllib/*.*
。 如果某个服务器只接受User-Agent
为Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 FireFox/2.0.0.11
的请求, 则使用urllib2
的脚本发起的网络请求会被过滤掉。这样做的好处是可以让服务器只接受来自浏览器的请求,而不是脚本发起的请求。 当然这种限制也不是绝对的,可以手动修改
User-Agent
键值达到目的。 因此,Python 文档用了spoof
这个词(“糊弄”User-Agent
)。
最后两个参数和三方的
HTTP cookies
解析有关:origin_req_host
默认为
cookielib.request_host(self)
,表示请求指定的服务器主机名或者 IP 地址。 例如,如果请求的是 HTML 文档,则该参数是目标网页的主机名:1 2 3
import urllib2, cookielib request = urllib2.Request('http://www.baidu.com') host_name = cookielib.request_host(request) # 'www.baidu.com'
unverifiable
表示请求是否可验证(RFC 2965
),默认为False
。 对于一个不可验证的请求对应的 URL,用户是无权决定是否访问的。 例如,请求 HTML 文档中的图片,用户无权决定是否自动获取该图片,则这个参数设为True
注意
许多网页就是这样,不受用户控制,自动弹出。
Request
实例¶
包含以下公有方法:
add_data(data)
get_method()
"POST"/"GET"/...
,仅对 HTTP 请求有意义。has_data()
get_data()
add_header(key,val)
给请求头添加新的键值对,只有 HTTP 处理器会受理这些键值对。
注解
键名不能相同,如果相同,则后一次的键值会覆盖前一次的键值。
add_unredirected_header(key,header)
添加一个键值对;如果需要做重定向,该键值对不会加入到重定向请求头中has_header(header)
请求头中是否含有指定键值对get_full_url()
返回构造函数提供的 URLget_type()
返回协议类型get_host()
返回主机名get_selector()
获取 URL 选择子set_proxy(host, type)
设置一个代理服务器,表示将生成一个代理请求实例。注解
host
覆盖get_host()
的返回值;type
覆盖get_type()
的返回值; 选择子是get_full_url()
的返回值。get_origin_req_host()
返回原始主机名(RFC 2965
)。is_unverifiable()
请求是否可验证。
OpenerDirector
实例¶
add_handler(handler)
增加一个处理器。
处理器将添加以下操作序列:
protocol_open()
打开协议 URLs;http_error_type()
处理 HTTP 错误对应的错误类型;protocol_error()
处理协议错误(HTTP 处理器会忽略该函数);protocol_request()
预处理协议请求;protocol_response()
后处理协议响应;
open(url[,data][,timeout])
注解
和
urlopen()
一样,不同的是,本函数使用局部访问器error(proto[,arg[,...]])
proto
指定协议类型;用协议指定的错误处理器处理当前协议错误。 返回一个收集错误信息的仿文件对象。
注解
HTTP 协议使用响应状态码指定错误处理器。
OpenerDirector
实例打开 URL 的几个阶段:
调用所有处理器的
protocol_request
,预处理请求。调用所有处理器的
protocol_open
,解析请求。如果某个处理器返回非
None
值(即服务器响应),或者抛出异常(通常为URLError
),这个阶段结束。 发生的异常允许继续传递。事实上,以上算法先尝试
default_open()
; 如果都返回None
,再尝试protocol_open()
; 如果返回None
,则再尝试unknown_open()
。处理器调用
protocol_response
,用于后处理响应。
BaseHandler
实例¶
BaseHandler
实例提供两个基础方法,可以直接调用:
add_parent(director)
添加一个访问器close()
删除所有访问器
重要
以下属性和方法只能在派生类中实现或使用:
parent 指定的
OpenerDirector
实例default_open(req)
派生类如果想获取所有的 URL,必须实现这个方法。
派生类如果实现了这个方法,则会被
add_parent()
指定的访问器对象调用。 它返回一个仿文件对象(如果没有访问器,则返回None
)。抛出异常
URLError
。重要
该方法在所有打开方法(
*_open()
)之前调用protocol_open(req)
注解
该方法的名称依据协议来定; 之后凡是
protocol_
开头的方法都是跟随协议名称的,不再复述。比如: HTTP 协议的打开方法为
http_open()
; ftp 协议的打开方法为ftp_open()
等。派生类如果想用指定的协议解析 URL,必须实现这个方法。
派生类如果实现了这个方法,则会被
add_parent()
指定的访问器对象调用。 它返回一个仿文件对象(如果没有访问器,则返回None
)。unknown_open(req)
派生类如果想不用任何处理器获取所有的 URL,必须实现这个方法。
参数说明和返回值以及异常类型和
protocol_open()
一样。http_error_default(req, fp, code, msg, hdrs)
派生类如果想捕获所有 HTTP 错误码,必须实现这个方法。
派生类如果实现了这个方法,则会被
add_parent()
指定的访问器对象调用。警告
用户不能调用这个方法
req
Request
实例fp
仿文件对象,指向 HTTP 错误消息体code
三个数字表示的错误码msg
用户可见的错误码的解释文字hdrs
一个字典对象,表示错误头的键值对
返回值与异常类型和
urlopen()
相同。http_error_nnn(req, fp, code, msg, hdrs)
派生类如果想捕获 HTTP 错误码
nnn
,必须实现这个方法。派生类如果实现了这个方法,发生错误码
nnn
时,add_parent()
指定的访问器对象会自动调用对应的http_error_nnn()
方法。参数说明和返回值以及异常类型和
http_error_default()
一样。protocol_request(req)
如果派生类想要预处理指定协议的请求实例,必须实现这个方法。
派生类如果实现了这个方法,则会被
add_parent()
指定的访问器对象调用。req
是预处理前的Request
实例,返回的是预处理后的Request
实例。protocol_response(req, response)
派生类如果想后处理指定协议的服务器响应,必须实现这个方法。
派生类如果实现了这个方法,则会被
add_parent()
指定的访问器对象调用。req
是一个Request
实例response
有和urlopen()
返回的对象一样的方法。
HTTPRedircetHandler
实例¶
redirect_request(req, fp, code, msg, hdrs, newurl)
返回一个
Request
实例或者None
。如果服务器返回一个重定向的响应(即错误响应消息
301
302
等等), 则在方法http_error_30*()
中自动调用redirect_request()
方法。 然后用生成的请求实例发出新的网络请求,以重定向到新的 URL。 如果没有处理器可以解析新的 URL,则抛出HTTPError
异常; 如果HTTPRedircetHandler
不能解析新的 URL,但存在其他处理器可以解析,则返回None
。http_error_301(req, fq, code, msg, hdrs)
当服务器返回
moved permanently
消息时,add_parent()
指定的访问器会调用http_error_301()
。http_error_302(req, fp, code, msg, hdrs)
当服务器返回
found
消息时,add_parent()
指定的访问器会调用http_error_301()
。http_error_303(req, fp,code, msg, hdrs)
当服务器返回
see other
消息时,add_parent()
指定的访问器会调用http_error_301()
。http_error_307(req, fp, code, msg, hdrs)
当服务器返回
temporary redirect
消息时,add_parent()
指定的访问器会调用http_error_301()
。
BaseHTTPServer¶
注解
本模块针对的是 HTTP 协议。
BaseHTTPServer
模块定义了两个类,用于构造 HTTP 服务器。
通常这两个类不直接拿来使用,而作为基类进行派生。
BaseHTTPServer.HTTPServer(server_address, RequestHandlerClass)
SocketServer.TCPServer
的子类,实现了SocketServer.BaseServer
的接口。HTTPServer
创建和监听HTTP socket
,分发请求给处理器。创建和运行服务器的代码示例:
1 2 3 4
def run(server_class=BaseHTTPServer.HTTPServer, handler_class=BaseHTTPServer.BaseHTTPRequestHandler): server_address = ('', 3000) httpd = server_class(server_address, handler_class) httpd.serve_forever()
构造函数参数说明:
- server_address 二元组
(server_name, server-port)
; 如果server_name
是 ‘’,表示服务器为本主机。 - RequestHandlerClass 请求处理器类名,可以传递
BaseHTTPServer.BaseHTTPRequestHandler
。
- server_address 二元组
BaseHTTPServer.BaseHTTPRequestHandler
定义处理器对象,用于解析服务器接收的 HTTP 请求。 它的实例不参与解析 HTTP 请求,一般是通过它的子类实例来完成。
处理器解析请求和头信息之后,调用与请求类型对应的方法。 例如:请求类型为
SPAM
,则对应的方法为do_SPAM()
。 该方法不带任何参数。重要
BaseHTTPServer.BaseHTTPRequestHandler
的子类不需要修改__init__()
方法。
BaseHTTPRequestHandler
的实例变量¶
client_address
是一个二元组(host, port)
,表示客户端主机地址server
BaseHTTPServer
实例command
请求类型,如GET
path
请求路径例如:客户端请求 URL 为:
http://127.0.0.1:2000/search?name=huwz&pwd=123456
,则 path 为/search?name=huwz&pwd=123456
。request_version
请求的协议版本,例如:HTTP/1.0
headers
类变量 MessageClass<message_class>` 的值是一个类对象。
headers
就是这个类对象的实例,用于解析和管理 HTTP 请求头。rfile
输入流,指向用户请求中附带数据的起始位置wfile
输出流,指向服务器响应数据的起始位置,返回给客户端
BaseHTTPRequestHandler
的类变量¶
server_version
表示服务器软件版本,可以修改它的值;
server_version
由多个字符串构成,字符串之间以空格隔开。 每个字符串的格式:<name>[/<version>]
,例如:BaseHTTP/0.2
sys_version
表示 Python 系统版本,采取
server_version
或者version_string()
支持的格式。如Python/1.4
。error_message_format
指定一个格式化字符串,用于构建错误响应消息,发送给客户端。
其中:
code
是整数,表示 HTTP 错误码;message
为错误简略信息,explain
为错误详细解释。默认的
message
和explain
可以从类变量responses
中获取。error_content_type
指定服务器错误响应头的
Content-Type
值。 默认值为text/html
。protocol_version
定义服务器响应的 HTTP 协议版本。 如果设为
HTTP/1.1
,则服务器允许 HTTP 长连接; 服务器所有响应的 HTTP 头必须设置准确的Content-Length
(send_header()
)。 出于后向兼容的考虑,默认版本为HTTP/1.0
。
MessageClass
表示仿
rfc822.Message
类,用于解析 HTTP 头。 默认值为mimetools.Message
,子类一般不会修改它。resposnes
{code:(shormessage, longmessage)}
它是一个字典,表示错误码到
(短信息, 长信息)
的映射(符合error_message_format
指定的格式)。
BaseHTTPRequestHandler
的方法¶
handle()
处理接收的 HTTP 请求,会调用一次
handle_one_request()
,启动长连接之后,会调用多次。 子类不用修改它;只要实现合适的do_*()
方法即可。handle_one_request()
解析和分发请求到合适的
do_*()
方法中。 子类不用修改它。send_error(code[,message])
发送错误码和错误信息给客户端。
code
表示 HTTP 错误码;message
是可选的。发完头信息之后,发送错误信息文本(由
error_message_format
构建)。send_response(code[,message])
发送一个响应头(类似于
HTTP/1.1 200 OK
),打印与接收请求相关的日志; 之后发送服务器头(version_string()
)和数据头(data_time_string()
)。send_header(keyword, value)
给输出流的 HTTP 头增加一个键值对。
end_headers()
给输出流的 HTTP 头增加一个空白行,表示结束
log_request([code][,size])
成功接收请求时,打印日志到标准输出流。
code
为 HTTP 响应状态码;size
表示响应消息体的长度。log_error(...)
不能完成请求时,打印错误日志。 默认情况下,将信息传递给
log_message()
。log_message(format, ...)
将任意信息发送给
sys.stderr
。每个打印消息都会在前面加上客户端的 ip 地址,当前日期和时间。
version_string()
返回服务器软件版本字符串; 由
server_version
和sys_version
组合而成。date_time_string([timestamp])
返回指定时间戳(
time.time()
)的日期和时间;用于消息头。如果参数
timestamp
省略,则使用当前日期和时间。其格式类似于:
Sun, 08 Feb 2015 23:09:30 GMT
log_date_time_string()
返回当前日期和时间,用于日志打印。
address_string()
返回客户端的地址,用于日志打印。 主机名称通过客户端 IP 地址查找。
注解
log_message()
内部调用 log_data_time_string()
和 address_string()
方法
unittest
¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import unittest
class TestAdd(unittest.TestCase):
def setUp(self):
print 'hello'
def tearDown(self):
print 'world'
def test_add(self):
self.assertEqual(3, 12)
def test_sub(self):
self.assertEqual(4, 4)
if __name__ == '__main__':
unittest.main()
|
在执行每个测试案例之前,都是执行 setUp()
;
案例运行结束之后,都会执行 tearDown()
。
以上的案例会运行两次 setUp()
和两次 tearDown()
可以定义类函数 setupClass()
和 tearDownClass()
:
1 2 3 4 5 6 7 | @classmethod
def setupClass(cls):
<code here>
@classmethod
def tearDownClass(cls):
<code here>
|
所有测试案例执行之前执行一次 setupClass()
;
所有测试案例执行之后执行一次 tearDownClass()
。
注解
测试类中以 test_
开始的类方法都是一个测试案例。