Python Standard Library

翻译: Python 江湖群

2008-03-28 13:33:37


[index.html 返回首页]


1. 其他模块


1.1. 概览

本章介绍了一些平台相关的模块. 重点放在了适用于整个平台家族的模块上. (比如 Unix , Windows 家族)


1.2. fcntl 模块

(只用于 Unix) fcntl 模块为 Unix上的 ioctlfcntl 函数提供了一个接口. 它们用于文件句柄和 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*

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 注册表数据库的一个基本接口.

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*


PythonStandardLib/chpt12 (last edited 2009-12-25 07:16:01 by localhost)