前面讲述了如何来处理进程参数和输入/输出, 本周我将探讨一些操作文件和目录的函数.
os模块中包含了一些函数集用于处理底层的文件描述符(当前进程打开属主文件所使用的整型), 相比file()对象来说这些是更底层的API, 在本文中将不会解释什么是文件描述符, 它通常可以很好的和file()对象协同工作, 更多细节可以参考 这里 来了解如何使用文件描述符.
os.access()可以测试一个进程对一个文件是否有可访问权限.
import os
print 'Testing:', __file__
print 'Exists:', os.access(__file__, os.F_OK)
print 'Readable:', os.access(__file__, os.R_OK)
print 'Writable:', os.access(__file__, os.W_OK)
print 'Executable:', os.access(__file__, os.X_OK)
这个结果将取决于你如何来运行这个示例程序, 可能会显示如下:
$ python os_access.py
Testing: os_access.py
Exists: True
Readable: True
Writable: True
Executable: False
os.access()模块包含了2个特殊的含义, 首先, 在实际使用open()函数之前使用os.access()函数来判断一个文件是否可访问是没有意义的. 这里有个小事实, 在函数的两次调用之间可能会改变文件的权限. 另外一个含义是该函数适合于大部分扩展的POSIX许可语义的网络文件系统. 文件系统对于一个进程对文件有访问权限的POSIX调用会做出响应, 在调用open()时, 因为某些原因没有通过POSIX的调用测试, 那么会报告失败. 总之, 最好时在特定的模式中使用open(), 如果出现错误还可以捕获IOError异常.
如果想获得更多关于文件的信息, 可以查阅stat()或者os.lstat(如果你查看的文件一个动态链接的话).
import os
import sys
import time
if len(sys.argv) == 1:
filename = __file__
else:
filename = sys.argv[1]
stat_info = os.stat(filename)
print 'os.stat(%s):' % filename
print '\tSize:', stat_info.st_size
print '\tPermissions:', oct(stat_info.st_mode)
print '\tOwner:', stat_info.st_uid
print '\tDevice:', stat_info.st_dev
print '\tLast modified:', time.ctime(stat_info.st_mtime)
再次申明, 你得到的结果将取决于你运行的方式, 可以尝试向os_stat.py传递不同的文件名看看.
$ python os_stat.py
os.stat(os_stat.py):
Size: 1547
Permissions: 0100644
Owner: 527
Device: 234881026
Last modified: Sun Jun 10 08:13:26 2007
在Unix类型系统上, 文件权限可以由chmod()来修改, 以整形形式传递. 形式值可以用stat模块的常量值来b表示. 以下示例了如何来触发用户的可执行权限位.
import os
import stat
# Determine what permissions are already set using stat
existing_permissions = stat.S_IMODE(os.stat(__file__).st_mode)
if not os.access(__file__, os.X_OK):
print 'Adding execute permission'
new_permissions = existing_permissions | stat.S_IXUSR
else:
print 'Removing execute permission'
# use xor to remove the user execute permission
new_permissions = existing_permissions ^ stat.S_IXUSR
os.chmod(__file__, new_permissions)
运行该脚本前假设你有修改文件模式的权限.
$ python os_stat_chmod.py
Adding execute permission
$ python os_stat_chmod.py
Removing execute permission
同样提供了一些处理文件系统中目录的函数, 包括创建内容列表和删除它们.
import os
dir_name = 'os_directories_example'
print 'Creating', dir_name
os.makedirs(dir_name)
file_name = os.path.join(dir_name, 'example.txt')
print 'Creating', file_name
f = open(file_name, 'wt')
try:
f.write('example file')
finally:
f.close()
print 'Listing', dir_name
print os.listdir(dir_name)
print 'Cleaning up'
os.unlink(file_name)
os.rmdir(dir_name)
$ python os_directories.py
Creating os_directories_example
Creating os_directories_example/example.txt
Listing os_directories_example
['example.txt']
Cleaning up
有2个函数集用来创建和删除目录, 当使用os.mkdir()创建一个新的目录时, 其父目录必须存在. 当使用os.rmdir()来删除一个目录时候, 那么只有目录树的叶子节点(目录的最后一级)可以被删除. 相比下, os.makedirs()和os.removedirs()可以操作当前路径下的所有目录, os.makedirs()可以创建路径不存在的目录, os.removedirs()可以删除包含父目录的子目录(当然前提有这个权限).
很多文件系统和平台都支持它, 同样有一些函数可以用来处理它们.
import os, tempfile
link_name = tempfile.mktemp()
print 'Creating link %s->%s' % (link_name, __file__)
os.symlink(__file__, link_name)
stat_info = os.lstat(link_name)
print 'Permissions:', oct(stat_info.st_mode)
print 'Points to:', os.readlink(link_name)
# Cleanup
os.unlink(link_name)
虽然os中包含了os.temparm()来创建临时文件, 当时相比tempfile模块还不够安全, 在使用中可能会产生RuntimeWarning信息, 更好的方法使用tempfile模块.
$ python os_symlinks.py
Creating link /tmp/tmpRxRiHn->os_symlinks.py
Permissions: 0120755
Points to: os_symlinks.py
os.walk()可以递归遍历一个目录, 对于每一个目录, 可以产生一个包含目录路径、当前路径的子目录列表, 以及在子目录中的文件. 以下示例展示了一个遍历目录的简单方法:
import os, sys
# If we are not given a path to list, use /tmp
if len(sys.argv) == 1:
root = '/tmp'
else:
root = sys.argv[1]
for dir_name, sub_dirs, files in os.walk(root):
print '\n', dir_name
# Make the subdirectory names stand out with /
sub_dirs = [ '%s/' % n for n in sub_dirs ]
# Mix the directory contents together
contents = sub_dirs + files
contents.sort()
# Show the contents
for c in contents:
print '\t%s' % c
$ python os_walk.py
/tmp
.KerberosLogin-0--1074266944 (inited,root,local)/
.KerberosLogin-527-4839472 (inited,gui,tty,local)/
527/
cs_cache_lock_527
cs_cache_lock_92
emacs527/
fry.log
hsperfdata_dhellmann/
objc_sharing_ppc_4294967294
objc_sharing_ppc_527
objc_sharing_ppc_92
svn.arg.1835l59
var_backups/
/tmp/.KerberosLogin-527-4839472 (inited,gui,tty,local)
KLLCCache.lock
/tmp/527
/tmp/emacs527
server
/tmp/hsperfdata_dhellmann
976
/tmp/var_backups
infodir.bak
local.nidump
下次, 我们讨论os模块中创建和管理进程的函数.