Python Standard Library
翻译: Python 江湖群
2008-03-28 13:33:37
Contents
[index.html 返回首页]
1. 其他模块
1.1. 概览
本章介绍了一些平台相关的模块. 重点放在了适用于整个平台家族的模块上. (比如 Unix , Windows 家族)
1.2. fcntl 模块
(只用于 Unix) fcntl 模块为 Unix上的 ioctl 和 fcntl 函数提供了一个接口. 它们用于文件句柄和 I/O 设备句柄的 "out of band" 操作, 包括读取扩展属性, 控制阻塞. 更改终端行为等等. (out of band management: 指使用分离的渠道进行设备管理. 这使系统管理员能在机器关机的时候对服务器, 网络进行监视和管理. 出处: http://en.wikipedia.org/wiki/Out-of-band_management )
关于如何在平台上使用这些函数, 请查阅对应的 Unix man 手册.
该模块同时提供了 Unix 文件锁定机制的接口. Example 12-1 展示了如何使用 flock 函数, 更新文件时为文件设置一个 advisory lock .
输出结果是由同时运行 3 个副本得到的. 像这样(都在一句命令行里):
python fcntl-example-1.py& python fcntl-example-1.py& python fcntl-example-1.py&
如果你注释掉对 flock 的调用, 那么 counter 文件不会正确地更新.
1.2.0.1. Example 12-1. Using the fcntl Module
File: fcntl-example-1.py
import fcntl, FCNTL
import os, time
FILE = "counter.txt"
if not os.path.exists(FILE):
# create the counter file if it doesn't exist
# 创建 counter 文件
file = open(FILE, "w")
file.write("0")
file.close()
for i in range(20):
# increment the counter
file = open(FILE, "r+")
fcntl.flock(file.fileno(), FCNTL.LOCK_EX)
counter = int(file.readline()) + 1
file.seek(0)
file.write(str(counter))
file.close() # unlocks the file
print os.getpid(), "=>", counter
time.sleep(0.1)
*B*30940 => 1
30942 => 2
30941 => 3
30940 => 4
30941 => 5
30942 => 6*b*
1.3. pwd 模块
(只用于 Unix) pwd 提供了一个到 Unix 密码/password "数据库"( /etc/passwd 以及相关文件 )的接口. 这个数据库(一般是一个纯文本文件)包含本地机器用户账户的信息. 如 Example 12-2 所示.
1.3.0.1. Example 12-2. 使用 pwd 模块
File: pwd-example-1.py
import pwd
import os
print pwd.getpwuid(os.getgid())
print pwd.getpwnam("root")
('effbot', 'dsWjk8', 4711, 4711, 'eff-bot', '/home/effbot', '/bin/bosh')
('root', 'hs2giiw', 0, 0, 'root', '/root', '/bin/bash')getpwall 函数返回一个包含所有可用用户数据库入口的列表. 你可以使用它搜索一个用户.
当需要查询很多名称的时候, 你可以使用 getpwall 来预加载一个字典, 如 Example 12-3 所示.
1.3.0.2. Example 12-3. 使用 pwd 模块
File: pwd-example-2.py
import pwd
import os
# preload password dictionary
_pwd = {}
for info in pwd.getpwall():
_pwd[info[0]] = _pwd[info[2]] = info
def userinfo(uid):
# name or uid integer
return _pwd[uid]
print userinfo(os.getuid())
print userinfo("root")
('effbot', 'dsWjk8', 4711, 4711, 'eff-bot', '/home/effbot', '/bin/bosh')
('root', 'hs2giiw', 0, 0, 'root', '/root', '/bin/bash')
1.4. grp 模块
(只用于 Unix) grp 模块提供了一个到 Unix 用户组/group ( /etc/group )数据库的接口. getgrgid 函数返回给定用户组 id 的相关数据(参见 Example 12-4 ), getgrnam 返回给定用户组名称的相关数据.
1.4.0.1. Example 12-4. 使用 grp 模块
File: grp-example-1.py
import grp
import os
print grp.getgrgid(os.getgid())
print grp.getgrnam("wheel")
*B*('effbot', '', 4711, ['effbot'])
('wheel', '', 10, ['root', 'effbot', 'gorbot', 'timbot'])*b*getgrall 函数返回包含所有可用用户组数据库入口的列表.
如果需要执行很多用户组查询, 你可以使用 getgrall 来把当前所有的用户组复制到一个字典里, 这可以节省一些时间. Example 12-5 中的 groupinfo 函数返回一个用户组 id ( int )或是 一个用户组名称( str )的信息.
1.4.0.2. Example 12-5. 使用 grp 模块缓存用户组信息
File: grp-example-2.py
import grp
import os
# preload password dictionary
_grp = {}
for info in grp.getgrall():
_grp[info[0]] = _grp[info[2]] = info
def groupinfo(gid):
# name or gid integer
return _grp[gid]
print groupinfo(os.getgid())
print groupinfo("wheel")
*B*('effbot', '', 4711, ['effbot'])
('wheel', '', 10, ['root', 'effbot', 'gorbot', 'timbot'])*b*
1.5. nis 模块
(只用于 Unix , 可选) nis 模块提供了 NIS ( Network Information Services , 网络信息服务 ,黄页) 服务的接口, 如 Example 12-6 所示. 它用于从可用的 NIS 数据库中获得数据.
1.5.0.1. Example 12-6. 使用 nis 模块
File: nis-example-1.py
import nis
import string
print nis.cat("ypservers")
print string.split(nis.match("bacon", "hosts.byname"))
*B*{'bacon.spam.egg': 'bacon.spam.egg'}
['194.18.155.250', 'bacon.spam.egg', 'bacon', 'spam-010']*b*
1.6. curses 模块
(只用于 Unix 可选) curses 模块提供了对文本字符终端窗口的控制, 它使用了一种独立于终端的方法. 如 Example 12-7 所示.
1.6.0.1. Example 12-7. 使用 curses 模块
File: curses-example-1.py
import curses
text = [
"a very simple curses demo",
"",
"(press any key to exit)"
]
# connect to the screen
# 连接到屏幕
screen = curses.initscr()
# setup keyboard
# 设置键盘
curses.noecho() # no keyboard echo
curses.cbreak() # don't wait for newline
# screen size
# 屏幕尺寸
rows, columns = screen.getmaxyx()
# draw a border around the screen
# 画一个边框
screen.border()
# display centered text
# 显示文字
y = (rows - len(text)) / 2
for line in text:
screen.addstr(y, (columns-len(line))/2, line)
y = y + 1
screen.getch()
curses.endwin()
1.7. termios 模块
(只用于 Unix , 可选) termios 为 Unix 的终端控制设备提供了一个接口. 它可用于控制终端通讯端口的大多方面.
Example 12-8 中, 该模块临时关闭了键盘回显(由第三个标志域的 ECHO 标志控制).
1.7.0.1. Example 12-8. 使用 termios 模块
File: termios-example-1.py
import termios, TERMIOS
import sys
fileno = sys.stdin.fileno()
attr = termios.tcgetattr(fileno)
orig = attr[:]
print "attr =>", attr[:4] # flags
# disable echo flag
attr[3] = attr[3] & ~TERMIOS.ECHO
try:
termios.tcsetattr(fileno, TERMIOS.TCSADRAIN, attr)
message = raw_input("enter secret message: ")
print
finally:
# restore terminal settings
termios.tcsetattr(fileno, TERMIOS.TCSADRAIN, orig)
print "secret =>", repr(message)
*B*attr => [1280, 5, 189, 35387]
enter secret message:
secret => 'and now for something completely different'*b*
1.8. tty 模块
(只用于 Unix) tty 模块包含一些用于处理 tty 设备的工具函数. Example 12-9 将终端窗口切换为 "raw" 模式.
1.8.0.1. Example 12-9. 使用 tty 模块
File: tty-example-1.py
import tty
import os, sys
fileno = sys.stdin.fileno()
tty.setraw(fileno)
print raw_input("raw input: ")
tty.setcbreak(fileno)
print raw_input("cbreak input: ")
os.system("stty sane") # ...
*B*raw input: this is raw input
cbreak input: this is cbreak input*b*
1.9. resource 模块
(只用于 Unix , 可选) resource 模块用于查询或修改当前系统资源限制设置. Example 12-10 展示了如何执行查询操作, Example 12-11 展示了如何执行修改操作.
1.9.0.1. Example 12-10. 使用 resource 模块查询当前设置
File: resource-example-1.py import resource print "usage stats", "=>", resource.getrusage(resource.RUSAGE_SELF) print "max cpu", "=>", resource.getrlimit(resource.RLIMIT_CPU) print "max data", "=>", resource.getrlimit(resource.RLIMIT_DATA) print "max processes", "=>", resource.getrlimit(resource.RLIMIT_NPROC) print "page size", "=>", resource.getpagesize() *B*usage stats => (0.03, 0.02, 0, 0, 0, 0, 75, 168, 0, 0, 0, 0, 0, 0, 0, 0) max cpu => (2147483647, 2147483647) max data => (2147483647, 2147483647) max processes => (256, 256) page size => 4096*b*
1.9.0.2. Example 12-11. 使用 resource 模块限制资源
File: resource-example-2.py
import resource
resource.setrlimit(resource.RLIMIT_CPU, (0, 1))
# pretend we're busy
for i in range(1000):
for j in range(1000):
for k in range(1000):
pass
*B*CPU time limit exceeded*b*
1.10. syslog 模块
(只用于 Unix 可选) syslog 模块用于向系统日志设备发送信息( syslogd ). 这些信息如何处理依不同的系统而定, 通常会被记录在一个 log 文件中, 例如 /var/log/messages , /var/adm/syslog , 或者其他类似处理. (如果你找不到这个文件, 请联系你的系统管理员). Example 12-12 展示了该模块的使用.
1.10.0.1. Example 12-12. 使用 syslog 模块
File: syslog-example-1.py import syslog import sys syslog.openlog(sys.argv[0]) syslog.syslog(syslog.LOG_NOTICE, "a log notice") syslog.syslog(syslog.LOG_NOTICE, "another log notice: %s" % "watch out!") syslog.closelog()
1.11. msvcrt 模块
(只用于 Windows/DOS ) msvcrt 模块用于访问 Microsoft Visual C/C++ Runtime Library (MSVCRT) 中函数的方法.
Example 12-13 展示了 getch 函数, 它用于从命令行读取一次按键操作.
1.11.0.1. Example 12-13. 使用 msvcrt 模块获得按键值
File: msvcrt-example-1.py
import msvcrt
print "press 'escape' to quit..."
while 1:
char = msvcrt.getch()
if char == chr(27):
break
print char,
if char == chr(13):
print
*B*press 'escape' to quit...
h e l l o*b*kbhit 函数在按键时返回(这样的捕获操作不会让 getch 阻塞), 如 Example 12-14 所示.
1.11.0.2. Example 12-14. 使用 msvcrt 模块接受键盘输入
File: msvcrt-example-2.py
import msvcrt
import time
print "press SPACE to enter the serial number"
while not msvcrt.kbhit() or msvcrt.getch() != " ":
# do something else
print ".",
time.sleep(0.1)
print
# clear the keyboard buffer
# 清除键盘缓冲区
while msvcrt.kbhit():
msvcrt.getch()
serial = raw_input("enter your serial number: ")
print "serial number is", serial
*B*press SPACE to enter the serial number
. . . . . . . . . . . . . . . . . . . . . . . .
enter your serial number: 10
serial number is 10*b*- 译注: 某翻译在这里评注道: 我能在 cmd 下运行. 用别的 IDLE 要不然卡住, 要不然接受不了键盘输入. 原因未知. 这是因为 IDLE 启动两个 python 线程, 使用 socket 发送数据, 获得程序返回的.
locking 函数实现了 Windows 下的跨进程文件锁定, 如 Example 12-15 所示.
1.11.0.3. Example 12-15. 使用 msvcrt 模块锁定文件
File: msvcrt-example-3.py
import msvcrt
import os
LK_UNLCK = 0 # unlock the file region 解锁区域
LK_LOCK = 1 # lock the file region 锁定文件区域
LK_NBLCK = 2 # non-blocking lock 非阻塞文件锁
LK_RLCK = 3 # lock for writing 为写入文件提供锁定
LK_NBRLCK = 4 # non-blocking lock for writing 为写入文件提供的非阻塞锁定
FILE = "counter.txt"
if not os.path.exists(FILE):
file = open(FILE, "w")
file.write("0")
file.close()
for i in range(20):
file = open(FILE, "r+")
# look from current position (0) to end of file
msvcrt.locking(file.fileno(), LK_LOCK, os.path.getsize(FILE))
counter = int(file.readline()) + 1
file.seek(0)
file.write(str(counter))
file.close() # unlocks the file
print os.getpid(), "=>", counter
time.sleep(0.1)
*B*208 => 21
208 => 22
208 => 23
208 => 24
208 => 25
208 => 26*b*
1.12. nt 模块
(非直接使用模块, 只用于 Windows ) nt 模块是 os 模块在 Windows 平台下调用的执行模块. 几乎没有任何原因直接使用这个模块, 请使用 os 模块替代. Example 12-16 展示了它的使用.
1.12.0.1. Example 12-16. 使用 nt 模块
File: nt-example-1.py
import nt
# in real life, use os.listdir and os.stat instead!
for file in nt.listdir("."):
print file, nt.stat(file)[6]
*B*aifc-example-1.py 314
anydbm-example-1.py 259
array-example-1.py 48*b*
1.13. _winreg 模块
(只用于 Windows , 2.0 中新增) _winreg 模块提供了访问 Windows 注册表数据库的一个基本接口.
Example 12-17 展示了它的使用.
1.13.0.1. Example 12-17. 使用 _winreg 模块
File: winreg-example-1.py
import _winreg
explorer = _winreg.OpenKey(
_winreg.HKEY_CURRENT_USER,
"Software\\Microsoft\\Windows\CurrentVersion\\Explorer"
)
# list values owned by this registry key
# 列出该注册表键下的所有值
try:
i = 0
while 1:
name, value, type= _winreg.EnumValue(explorer, i)
print repr(name),
i += 1
except WindowsError:
print
value, type = _winreg.QueryValueEx(explorer, "Logon User Name")
print
print "user is", repr(value)
*B*'Logon User Name' 'CleanShutdown' 'ShellState' 'Shutdown Setting'
'Reason Setting' 'FaultCount' 'FaultTime' 'IconUnderline'...
user is u'Effbot'*b*
1.14. posix 模块
(非直接使用模块, 只用于 Unix/POSIX ) posix 模块是 os 模块在 Unix 及其他 POSIX 系统下使用的实现模块. 一般只需要通过 os 模块访问它即可. 如 Example 12-18 所示.
1.14.0.1. Example 12-18. 使用 posix 模块
File: posix-example-1.py
import posix
for file in posix.listdir("."):
print file, posix.stat(file)[6]
*B*aifc-example-1.py 314
anydbm-example-1.py 259
array-example-1.py 48*b*