Python 3 带有一个模块叫做 os,代表 “操作系统(operating system)。” os 模块 包含非常多的函数用于获取(和修改)本地目录、文件进程、环境变量等的信息。Python 尽最大的努力在所有支持的操作系统上提供一个统一的API, 这样你就可以在保证程序能够在任何的计算机上运行的同时尽量少的包含平台特定的代码。
当前
工作目录
当你
刚刚开始学习Python的时候, 你将花大量的时间在 PyShell上。 在整本书中,你将一直看见类似下面的例子:
1.
在examples 目录导入某一个模块
2. 调用模块的某一个函数
3. 解释输出结果
总是
有一个当前工作目录
如果
你不知道当前工作目录, 第一步很可能会得到一个ImportError。 为什么? 因为 Python 将在导入搜索路径中查找示例模块, 但是由于examples 目录没有包含在搜索路径中,查找将失败。 你可以通过下面两个方法之一来解决这个问题:
1. 将examples目录加入到导入搜索路径中
2. 将当前工作目录切换到examples目录
Python在任何时候都在暗地里记住了当前工作目录这个属性。无论你是在Python Shell 中,还是在命令行运行你自己的Python 脚本,抑或是在Web 服务器上运行Python CGI 脚本,当前工作目录总是存在。
os 模块提供了两个函数处理当前工作目录

>>> import os ①
 >>> print(os.getcwd()) ②
 C:\Python31
 >>> os.chdir('/Users/pilgrim/diveintopython3/examples') ③
 >>
 > print(os.getcwd()) ④
 C:
 \Users\pilgrim\diveintopython3\examples


1.
os 是Python 自带的; 你可以在任何时间,任何地方导入它。
2.
使用os.getcwd() 函数获得当前工作目录。当你运行一个图形化的Python Shell 时,当前工作目录默认将是Python Shell的可执行文件所在的目录。在Windows 上, 这个目录取决于你将Python安装在哪里; 默认位置是 c:\Python31。如果你通过命令行运行Python Shell,当前工作目录是你运行python3时所在的目录。
3. 使用os.chdir()函数改变当前工作目录
4. 运行os.chdir()函数时,即使在Windows上,我也总是使用Linux风格的路径(正斜杠,没有盘符)。这就是Python 尝试隐藏操作系统差异的一个地方。
处理文件名和目录名
既然我们说到了目录,我得指出 os.path 模块。os.path 模块包含了操作文件名和目录名的函数.

>>> import os
 >>> print(os.path.join('/Users/pilgrim/diveintopython3/examples/', 'humansize.py')) ①
 /Users/pilgrim/diveintopython3/examples/humansize.py
 >>> print(os.path.join('/Users/pilgrim/diveintopython3/examples', 'humansize.py')) ②
 /Users/pilgrim/diveintopython3/examples\humansize.py
 >>> print(os.path.expanduser('~')) ③
 c:\Users\pilgrim
 >>
 > print(os.path.join(os.path.expanduser('~'), 'diveintopython3', 'examples', 'humansize.py')) ④
 c:
 \Users\pilgrim\diveintopython3\examples\humansize.py

os.path.join() 函数从一个或多个路径片段中构造一个路径名。 在这个例子中, 它仅仅是简单的拼接字符串.
2.
这个例子稍微复杂一点, 在和文件名拼接前,join函数给路径名添加一个额外的斜杠。由于我在Windows 上写这个例子, 这个斜杠是一个反斜杠而不是正斜杠。如果你在Linux 或者Mac OS X上重现这个例子, 你将会看见正斜杠. 无论你使用哪种形式的斜杠,Python 都可以访问到文件。
3. os.path.expanduser() 用来将包含~符号(表示当前用户Home目录)的路径扩展为完整的路径。在任何有Home 目录概念的操作系统上(包括Linux,Mac OS X 和Windows),这个函数都能工作。返回的路径不以斜杠结尾,但是os.path.join()并不介意这一点。
4. 结合这些技术,你可以很方便的构造出用户Home 目录下的文件和目录的路径。 os.path.join()可以接受任何数量的参数。当我发现这一点时我大喜过望, 因为在一门新的语言中构造我的工具箱时,addSlashIfNecessary()总是我不得不写的愚蠢的小函数之一。不要 在Python 中写这个愚蠢的小函数,聪明的人们已经帮你考虑过这个问题了。
os.path 也包含用于分割完整路径名,目录名和文件名的函数

>>> pathname = '/Users/pilgrim/diveintopython3/examples/humansize.py'
 >>> os.path.split(pathname) ①
 ('/Users/pilgrim/diveintopython3/examples', 'humansize.py')
 >>> (dirname, filename) = os.path.split(pathname) ②
 >>> dirname ③
 '/Users/pilgrim/diveintopython3/examples'
 >>> filename ④
 'humansize.py'
 >>> (shortname, extension) = os.path.splitext(filename) ⑤
 >>> shortname
 'humansize'
 >>
 > extension
 '.
 py'
 1.


split 函数分割一个完整路径并返回目录和文件名。
2.
还记得我说过在函数返回多个值时应该使用多变量赋值 吗 ? os.path.split() 函数正是这样做的。 将split函数的返回值赋值给一个二元组。每个变量获得了返回元组中的对应元素的值。
3.
第一个变量dirname,获得了os.path.split() 函数返回元组中的第一个元素,文件所在的目录。
4. 第二个变量filename,获得了os.path.split() 函数返回元组中的第二个元素,文件名。
5. os.path 也包含os.path.splitext() 函数,它分割一个文件名并返回短文件名和扩展名。可以使用同样的技术将它们的值赋值给不同的变量。
罗列目录内容
glob 模块是Python标准库中的另一个工具,它可以通过编程的方法获得一个目录的内容,并且它使用熟悉的命令行下的通配符。 glob 模块使用shell风格的通配符。

>>> os.chdir('/Users/pilgrim/diveintopython3/')
 >>> import glob
 >>> glob.glob('examples/*.xml') ①
 ['examples\\feed‐broken.xml',
 'examples\\feed‐ns0.xml',
 'examples\\feed.xml']
 >>> os.chdir('examples/') ②
 >>> glob.glob('*test*.py') ③
 ['alphameticstest.py',
 'pluraltest1.py',
 'pluraltest2.py',
 'pluraltest3.py',
 'pluraltest4.py',
 'pluraltest5.py',
 'pluraltest6.py',
 'romantest1.py',
 'romantest10.py',
 'romantest2.py',
 'romantest3.py',
 'romantest4.py',
 'romantest5.py',
 'romantest6.py',
 'romantest7.py',
 'r
 omantest8.py',
 'r
 omantest9.py']
 1.


glob 模块接受一个通配符并返回所有匹配的文件和目录的路径。在这个例子中,通配符是一个目录名加上 “*.xml”, 它匹配examples子目录下的所有.xml 文件。
2. 现在我们将当前工作目录切换到examples 目录。 os.chdir() 可以接受相对路径.
3. 在glob模式中你可以使用多个通配符。这个例子在当前工作目录中找出所有扩展名为.py并且在文件名中包含单词test 的文件。
获取文件元信息
每一个现代文件系统都对文件存储了元信息: 创建时间,最后修改时间,文件大小等等。Python 单独提供了一个的API 用于访问这些元信息。 你不需要打开文件。知道文件名就足够了。

>>> import os
 >>> print(os.getcwd()) ①
 c:\Users\pilgrim\diveintopython3\examples
 >>> metadata = os.stat('feed.xml') ②
 >>> metadata.st_mtime ③
 1247520344.9537716
 >>> import time ④
 >>> time.localtime(metadata.st_mtime) ⑤
 ti
 me.struct_time(tm_year=2009, tm_mon=7, tm_mday=13, tm_hour=17,
 tm
 _min=25, tm_sec=44, tm_wday=0, tm_yday=194, tm_isdst=1)
 1.


当前工作目录是examples 文件夹。
2.
feed.xml是examples 文件夹中的一个文件。 调用os.stat() 函数返回一个包含多种文件元信息的对象。
3.
st_mtime 是最后修改时间,它的格式不是很有用。(技术上讲,它是从纪元,也就是1970年1月1号的第一秒钟,到现在的秒数)
4. time 模块是Python标准库的一部分。 它包含用于在不同时间格式中转换,将时间格式化成字符串以及处理时区的函数。
5. time.localtime() 函数将从纪元到现在的秒数这个格式表示的时间(os.stat()函数返回值的st_mtime 属性)转换成更有用的包含年、月、日、小时、分钟、秒的结构体。这个文件的最后修改时间是2009年7月13日下午5:25。

# continued from the previous example
 >>> metadata.st_size ①
 3070


1. os.stat() 函数也通过st_size 属性返回文件大小。文件feed.xml 的大小是 3070 字节。
构造绝对路径
在前一节中,glob.glob() 函数返回一个相对路径的列表。第一个例子的路径类似'examples\feed.xml',而第二个例子的路但是当你希望构造一个从根目录开始或者是包含盘符的绝对路径时,你就需要用到os.path.realpath()函数了。

>>> import os
 >>> print(os.getcwd())
 c:\Users\pilgrim\diveintopython3\examples
 >>> print(os.path.realpath('feed.xml'))
 c:\Users\pilgrim\diveintopython3\examples\feed.xml