Skip to content

Commit 7e7e700

Browse files
committed
13.7小节完成
1 parent 1988b8e commit 7e7e700

File tree

1 file changed

+78
-74
lines changed

1 file changed

+78
-74
lines changed

source/c13/p07_copy_move_files_and_directories.rst

Lines changed: 78 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -5,54 +5,56 @@
55
----------
66
问题
77
----------
8-
You need to copy or move files and directories around, but you don’t want to do it by
9-
calling out to shell commands.
8+
你想哟啊复制或移动文件和目录,但是又不想调用shell命令。
109

1110
|
1211
1312
----------
1413
解决方案
1514
----------
16-
The shutil module has portable implementations of functions for copying files and
17-
directories. The usage is extremely straightforward. For example:
15+
``shutil`` 模块有很多便捷的函数可以复制文件和目录。使用起来非常简单,比如:
1816

19-
import shutil
17+
.. code-block:: python
2018
21-
# Copy src to dst. (cp src dst)
22-
shutil.copy(src, dst)
19+
import shutil
2320
24-
# Copy files, but preserve metadata (cp -p src dst)
25-
shutil.copy2(src, dst)
21+
# Copy src to dst. (cp src dst)
22+
shutil.copy(src, dst)
2623
27-
# Copy directory tree (cp -R src dst)
28-
shutil.copytree(src, dst)
24+
# Copy files, but preserve metadata (cp -p src dst)
25+
shutil.copy2(src, dst)
2926
30-
# Move src to dst (mv src dst)
31-
shutil.move(src, dst)
27+
# Copy directory tree (cp -R src dst)
28+
shutil.copytree(src, dst)
29+
30+
# Move src to dst (mv src dst)
31+
shutil.move(src, dst)
32+
33+
这些函数的参数都是字符串形式的文件或目录名。
34+
底层语义模拟了类似的Unix命令,如上面的注释部分。
3235

33-
The arguments to these functions are all strings supplying file or directory names. The
34-
underlying semantics try to emulate that of similar Unix commands, as shown in the
35-
comments.
36-
By default, symbolic links are followed by these commands. For example, if the source
37-
file is a symbolic link, then the destination file will be a copy of the file the link points
38-
to. If you want to copy the symbolic link instead, supply the follow_symlinks keyword
39-
argument like this:
36+
默认情况下,对于符号链接而已这些命令处理的是它指向的东西。
37+
例如,如果源文件是一个符号链接,那么目标文件将会是符号链接指向的文件。
38+
如果你只想复制符号链接本身,那么需要指定关键字参数 ``follow_symlinks`` ,如下:
4039

41-
shutil.copy2(src, dst, follow_symlinks=False)
40+
.. code-block:: python
41+
shutil.copy2(src, dst, follow_symlinks=False)
4242
43-
If you want to preserve symbolic links in copied directories, do this:
43+
如果你想保留被复制目录中的符号链接,像这样做:
4444

45-
shutil.copytree(src, dst, symlinks=True)
45+
.. code-block:: python
4646
47-
The copytree() optionally allows you to ignore certain files and directories during the
48-
copy process. To do this, you supply an ignore function that takes a directory name
49-
and filename listing as input, and returns a list of names to ignore as a result. For ex‐
50-
ample:
47+
shutil.copytree(src, dst, symlinks=True)
5148
52-
def ignore_pyc_files(dirname, filenames):
53-
return [name in filenames if name.endswith('.pyc')]
49+
``copytree()`` 可以让你在复制过程中选择性的忽略某些文件或目录。
50+
你可以提供一个忽略函数,接受一个目录名和文件名列表作为输入,返回一个忽略的名称列表。例如:
5451

55-
shutil.copytree(src, dst, ignore=ignore_pyc_files)
52+
.. code-block:: python
53+
54+
def ignore_pyc_files(dirname, filenames):
55+
return [name in filenames if name.endswith('.pyc')]
56+
57+
shutil.copytree(src, dst, ignore=ignore_pyc_files)
5658
5759
Since ignoring filename patterns is common, a utility function ignore_patterns() has
5860
already been provided to do it. For example:
@@ -64,47 +66,49 @@ shutil.copytree(src, dst, ignore=shutil.ignore_patterns('*~','*.pyc'))
6466
----------
6567
讨论
6668
----------
67-
Using shutil to copy files and directories is mostly straightforward. However, one
68-
caution concerning file metadata is that functions such as copy2() only make a best
69-
effort in preserving this data. Basic information, such as access times, creation times,
70-
and permissions, will always be preserved, but preservation of owners, ACLs, resource
71-
forks, and other extended file metadata may or may not work depending on the un‐
72-
derlying operating system and the user’s own access permissions. You probably wouldn’t
73-
want to use a function like shutil.copytree() to perform system backups.
74-
When working with filenames, make sure you use the functions in os.path for the
75-
greatest portability (especially if working with both Unix and Windows). For example:
76-
77-
>>> filename = '/Users/guido/programs/spam.py'
78-
>>> import os.path
79-
>>> os.path.basename(filename)
80-
'spam.py'
81-
>>> os.path.dirname(filename)
82-
'/Users/guido/programs'
83-
>>> os.path.split(filename)
84-
('/Users/guido/programs', 'spam.py')
85-
>>> os.path.join('/new/dir', os.path.basename(filename))
86-
'/new/dir/spam.py'
87-
>>> os.path.expanduser('~/guido/programs/spam.py')
88-
'/Users/guido/programs/spam.py'
89-
>>>
90-
91-
One tricky bit about copying directories with copytree() is the handling of errors. For
92-
example, in the process of copying, the function might encounter broken symbolic links,
93-
files that can’t be accessed due to permission problems, and so on. To deal with this, all
94-
exceptions encountered are collected into a list and grouped into a single exception that
95-
gets raised at the end of the operation. Here is how you would handle it:
96-
97-
try:
98-
shutil.copytree(src, dst)
99-
except shutil.Error as e:
100-
for src, dst, msg in e.args[0]:
101-
# src is source name
102-
# dst is destination name
103-
# msg is error message from exception
104-
print(dst, src, msg)
105-
106-
If you supply the ignore_dangling_symlinks=True keyword argument, then copy
107-
tree() will ignore dangling symlinks.
108-
The functions shown in this recipe are probably the most commonly used. However,
109-
shutil has many more operations related to copying data. The documentation is def‐
110-
initely worth a further look. See the Python documentation.
69+
使用 ``shutil`` 复制文件和目录也忒简单了点吧。
70+
不过,对于文件元数据信息,``copy2()`` 这样的函数只能尽自己最大能力来保留它。
71+
访问时间、创建时间和权限这些基本信息会被保留,
72+
但是对于所有者、ACLs、资源fork和其他更深层次的文件元信息就说不准了,
73+
这个还得依赖于底层操作系统类型和用户所拥有的访问权限。
74+
你通常不会去使用 ``shutil.copytree()`` 函数来执行系统备份。
75+
当处理文件名的时候,最好使用 ``os.path`` 中的函数来确保最大的可移植性(特别是同时要适用于Unix和Windows)。
76+
例如:
77+
78+
.. code-block:: python
79+
80+
>>> filename = '/Users/guido/programs/spam.py'
81+
>>> import os.path
82+
>>> os.path.basename(filename)
83+
'spam.py'
84+
>>> os.path.dirname(filename)
85+
'/Users/guido/programs'
86+
>>> os.path.split(filename)
87+
('/Users/guido/programs', 'spam.py')
88+
>>> os.path.join('/new/dir', os.path.basename(filename))
89+
'/new/dir/spam.py'
90+
>>> os.path.expanduser('~/guido/programs/spam.py')
91+
'/Users/guido/programs/spam.py'
92+
>>>
93+
94+
使用 ``copytree()`` 复制文件夹的一个棘手的问题是对于错误的处理。
95+
例如,在复制过程中,函数可能会碰到损坏的符号链接,因为权限无法访问文件的问题等等。
96+
为了解决这个问题,所有碰到的问题会被收集到一个列表中并打包为一个单独的异常,到了最后再抛出。
97+
下面是一个例子:
98+
99+
.. code-block:: python
100+
101+
try:
102+
shutil.copytree(src, dst)
103+
except shutil.Error as e:
104+
for src, dst, msg in e.args[0]:
105+
# src is source name
106+
# dst is destination name
107+
# msg is error message from exception
108+
print(dst, src, msg)
109+
110+
如果你提供关键字参数 ``ignore_dangling_symlinks=True`` ,
111+
这时候 ``copytree()`` 会忽略掉无效符号链接。
112+
113+
本节演示的这些函数都是最常见的。不过,``shutil`` 还有更多的和复制数据相关的操作。
114+
它的文档很值得一看,参考 `Python documentation <https://docs.python.org/3/library/shutil.html>`_

0 commit comments

Comments
 (0)