0.摘要
这一章节将围绕一个非常强大的技术向你介绍列表解析,字典解析和集合解析这三个概念。但是,我要先打个岔介绍两个帮助你浏览本地文件系统的模块。
1.处理文件和目录
P y t h o n 3 Python 3 Python3带有一个模块叫做 o s os os,代表 “操作系统(operating system)”。 o s os os模块 包含非常多的函数用于获取(和修改)本地目录、文件进程、环境变量等的信息。 P y t h o n Python Python尽最大的努力在所有支持的操作系统上提供一个统一的 a p i api api, 这样你就可以在保证程序能够在任何的计算机上运行的同时尽量少的包含平台特定的代码。
1.1当前工作目录
o
s
os
os是
P
y
t
h
o
n
Python
Python自带的; 你可以在任何时间,任何地方导入它。
使用
o
s
.
g
e
t
c
w
d
(
)
os.getcwd()
os.getcwd()函数获得当前工作目录。当你运行一个图形化的
P
y
t
h
o
n
S
h
e
l
l
Python\ Shell
Python Shell时,当前工作目录默认将是
P
y
t
h
o
n
S
h
e
l
l
Python\ Shell
Python Shell的可执行文件所在的目录。在
W
i
n
d
o
w
s
Windows
Windows上, 这个目录取决于你将
P
y
t
h
o
n
Python
Python安装在哪里; 如果你通过命令行运行
P
y
t
h
o
n
S
h
e
l
l
Python\ Shell
Python Shell,它是你运行
p
y
t
h
o
n
3
python3
python3时所在的目录。
使用
o
s
.
c
h
d
i
r
(
)
os.chdir()
os.chdir()函数改变当前工作目录。
运行
o
s
.
c
h
d
i
r
(
)
os.chdir()
os.chdir()函数时,即使在
W
i
n
d
o
w
s
Windows
Windows上,我也总是使用
L
i
n
u
x
Linux
Linux风格的路径(正斜杠,没有盘符)。这就是
P
y
t
h
o
n
Python
Python尝试隐藏操作系统差异的一个地方。
1.2处理文件名和目录名
o
s
.
p
a
t
h
.
j
o
i
n
(
)
os.path.join()
os.path.join()函数从一个或多个路径片段中构造一个路径名。 在这个例子中, 它仅仅是简单的拼接字符串。
这个例子稍微复杂一点,在和文件名拼接前,
j
o
i
n
join
join函数给路径名添加一个额外的斜杠。由于我在
W
i
n
d
o
w
s
Windows
Windows上写这个例子,这个斜杠是一个反斜杠而不是正斜杠。如果你在
L
i
n
u
x
Linux
Linux或者
M
a
c
O
S
X
Mac\ OS\ X
Mac OS X上重现这个例子,你将会看见正斜杠。 无论你使用哪种形式的斜杠,
P
y
t
h
o
n
Python
Python都可以访问到文件。
o
s
.
p
a
t
h
.
e
x
p
a
n
d
u
s
e
r
(
)
os.path.expanduser()
os.path.expanduser()用来将包含~符号(表示当前用户
H
o
m
e
Home
Home目录)的路径扩展为完整的路径。在任何有
H
o
m
e
Home
Home目录概念的操作系统上(包括
L
i
n
u
x
,
M
a
c
O
S
X
和
W
i
n
d
o
w
s
Linux,Mac\ OS\ X 和Windows
Linux,Mac OS X和Windows),这个函数都能工作。返回的路径不以斜杠结尾,但是
o
s
.
p
a
t
h
.
j
o
i
n
(
)
os.path.join()
os.path.join()并不介意这一点。
结合这些技术,你可以很方便的构造出用户
H
o
m
e
Home
Home目录下的文件路径。
o
s
.
p
a
t
h
.
j
o
i
n
(
)
os.path.join()
os.path.join()可以接受任何数量的参数。
s
p
l
i
t
split
split函数分割一个完整路径并返回目录和文件名。它会返回一个元组,所以可以使用多变量同时赋值。
o
s
.
p
a
t
h
.
s
p
l
i
t
e
x
t
(
)
os.path.splitext()
os.path.splitext()函数分割一个文件名并返回短文件名和扩展名。可以使用同样的技术将它们的值赋值给不同的变量。
1.3罗列目录内容
g
l
o
b
glob
glob模块接受一个通配符并返回所有匹配的文件和目录的路径。在这个例子中,通配符是一个目录名加上
∗
.
x
m
l
*.xml
∗.xml,它匹配
e
x
a
m
p
l
e
s
examples
examples子目录下的所有
.
x
m
l
.xml
.xml文件。
现在我们将当前工作目录切换到
e
x
a
m
p
l
e
s
examples
examples目录。
o
s
.
c
h
d
i
r
(
)
os.chdir()
os.chdir()可以接受相对路径。
在
g
l
o
b
glob
glob模式中你可以使用多个通配符。这个例子在当前工作目录中找出所有扩展名为
.
p
y
.py
.py并且在文件名中包含单词
t
e
s
t
test
test的文件。
1.4获取文件元信息
每一个现代文件系统都对文件存储了元信息: 创建时间,最后修改时间,文件大小等等。
P
y
t
h
o
n
Python
Python单独提供了一个的
a
p
i
api
api用于访问这些元信息。
调用
o
s
.
s
t
a
t
(
)
os.stat()
os.stat()函数返回一个包含多种文件元信息的对象。
s
t
_
m
t
i
m
e
st\_mtime
st_mtime是最后修改时间,它的格式不是很有用(技术上讲,它是从纪元,也就是1970年1月1号的第一秒钟,到现在的秒数)。
t
i
m
e
time
time模块是
P
y
t
h
o
n
Python
Python标准库的一部分。 它包含用于在不同时间格式中转换,将时间格式化成字符串以及处理时区的函数。
t
i
m
e
.
l
o
c
a
l
t
i
m
e
(
)
time.localtime()
time.localtime()函数将从纪元到现在的秒数这个格式表示的时间(
o
s
.
s
t
a
t
(
)
os.stat()
os.stat()函数返回值的
s
t
_
m
t
i
m
e
st\_mtime
st_mtime属性)转换成更有用的包含年、月、日、小时、分钟、秒的结构体。这个文件的最后修改时间是2009年7月13日下午5:25。
1.5构造绝对路径
在前一节中,
g
l
o
b
.
g
l
o
b
(
)
glob.glob()
glob.glob()函数返回一个相对路径的列表。只要你保持在当前工作目录中,你就可以使用这些相对路径来打开文件或者获得文件的元信息。但是当你希望构造一个从根目录开始或者是包含盘符的绝对路径时,你就需要用到
o
s
.
p
a
t
h
.
r
e
a
l
p
a
t
h
(
)
os.path.realpath()
os.path.realpath()函数了。
2.列表解析
为了理解这一点,请从右向左看。
a
_
l
i
s
t
a\_list
a_list是你要映射的列表。
P
y
t
h
o
n
Python
Python解释器逐个访问
a
_
l
i
s
t
a\_list
a_list的元素,并临时将元素赋值给变量
e
l
e
m
elem
elem。 然后
P
y
t
h
o
n
Python
Python对元素应用函数
e
l
e
m
∗
2
elem * 2
elem∗2并且将结果添加到返回列表中。
列表解析创造一个新的列表而不改变原列表。可以安全的将列表解析的结果赋值给被映射的变量。
P
y
t
h
o
n
Python
Python会在内存中构造新的列表,在列表解析完成后将结果赋值给原来的变量。
你可以在列表解析的最后加入
i
f
if
if子句来过滤列表。对于列表中每一个元素
i
f
if
if关键字后面的表达式都会被计算。如果表达式的计算结果为
T
r
u
e
True
True,那么这个元素将会被包含在输出中。这个列表解析在当前目录查找所有
.
p
y
.py
.py文件,而
i
f
if
if表达式通过测试文件大小是否大于
6000
6000
6000字节对列表进行过滤。有6个符合条件的文件,所以这个列表解析返回包含六个文件名的列表。
到目前为止的例子中的列表解析都只是用了一些简单的表达式, 乘以一个常数、调用一个函数或者是在过滤后返回原始元素。 然而列表解析并不限制表达式的复杂程度。
这个列表解析找到当前工作目录下的所有
.
x
m
l
.xml
.xml文件, 对于每一个文件构造一个包含文件大小(通过调用
o
s
.
s
t
a
t
(
)
os.stat()
os.stat()获得)和绝对路径(通过调用
o
s
.
p
a
t
h
.
r
e
a
l
p
a
t
h
(
)
os.path.realpath()
os.path.realpath())的元组。
3.字典解析
除了两点以外,字典解析的语法同列表解析很类似。首先,它被花括号而不是方括号包围;第二,对于每一个元素它包含由冒号分隔的两个表达式,而不是列表解析的一个。冒号前的表达式(在这个例子中是
f
f
f)是字典的键;冒号后面的表达式(在这个例子中是
o
s
.
s
t
a
t
(
f
)
os.stat(f)
os.stat(f))是值。
这个字典的键很简单,就是
g
l
o
b
.
g
l
o
b
(
′
∗
t
e
s
t
∗
.
p
y
′
)
glob.glob('*test*.py')
glob.glob(′∗test∗.py′)调用返回的文件名。每一个键对应的值是
o
s
.
s
t
a
t
(
)
os.stat()
os.stat()函数的返回值。
第一个字典解析获得当前目录下所有的文件的列表(
g
l
o
b
.
g
l
o
b
(
′
∗
′
)
glob.glob('*')
glob.glob(′∗′)),通过
o
s
.
s
t
a
t
(
f
)
os.stat(f)
os.stat(f)获得每一个文件的元信息, 然后构造一个键是文件名,值是文件元信息的字典。
第二个字典解析在前一个基础上过滤掉文件大小小于等于6000字节的文件,并用过滤出的列表构造字典,字典的键是文件名去掉扩展名的部分(
o
s
.
p
a
t
h
.
s
p
l
i
t
e
x
t
(
f
)
[
0
]
os.path.splitext(f)[0]
os.path.splitext(f)[0]) ,字典的值是每个文件的人类可读的近似大小(
h
u
m
a
n
s
i
z
e
.
a
p
p
r
o
x
i
m
a
t
e
_
s
i
z
e
(
m
e
t
a
.
s
t
_
s
i
z
e
)
humansize.approximate\_size(meta.st\_size)
humansize.approximate_size(meta.st_size))。