This document is for an old version of Python that is no longer supported. You should upgrade and read the Python 当前稳定版本的文档.

# 10.5. `filecmp` — 文件及目录的比较

源代码: Lib/filecmp.py

`filecmp` 模块定义了用于比较文件及目录的函数，并且可以选取多种关于时间和准确性的折衷方案。对于文件的比较，另见 `difflib` 模块。

`filecmp` 模块定义了如下函数：

`filecmp.``cmp`(f1, f2[, shallow])

  比较名为 f1 和 f2 的文件，如果它们似乎相等则返回 `True` ，否则返回 `False` 。

  Unless shallow is given and is false, files with identical `os.stat()` signatures are taken to be equal.

  Files that were compared using this function will not be compared again unless their `os.stat()` signature changes.

  需要注意，没有外部程序被该函数调用，这赋予了该函数可移植性与效率。

`filecmp.``cmpfiles`(dir1, dir2, common[, shallow])

  比较在两个目录 dir1 和 dir2 中，由 common 所确定名称的文件。

  返回三组文件名列表： match, mismatch, errors 。 match 含有相匹配的文件， mismatch 含有那些不匹配的，然后 errors 列出那些未被比较文件的名称。如果文件不存在于两目录中的任一个，或者用户缺少读取它们的权限，又或者因为其他的一些原因而无法比较，那么这些文件将会被列在 errors 中。

  参数 shallow 具有同 `filecmp.cmp()` 一致的含义与默认值。

  例如， `cmpfiles('a', 'b', ['c', 'd/e'])` 将会比较 `a/c` 与 `b/c` 以及 `a/d/e` 与 `b/d/e` 。 `'c'` 和 `'d/e'` 将会各自出现在返回的三个列表里的某一个列表中。

Example:

    >>> import filecmp
    >>> filecmp.cmp('undoc.rst', 'undoc.rst')
    True
    >>> filecmp.cmp('undoc.rst', 'index.rst')
    False

## 10.5.1. `dircmp` 类

`dircmp` instances are built using this constructor:

class `filecmp.``dircmp`(a, b[, ignore[, hide]])

  Construct a new directory comparison object, to compare the directories a and b. ignore is a list of names to ignore, and defaults to `['RCS', 'CVS', 'tags']`. hide is a list of names to hide, and defaults to `[os.curdir, os.pardir]`.

  `dircmp` 类如 `filecmp.cmp()` 中所描述的那样对文件进行 shallow 比较。

  `dircmp` 类提供以下方法：

  `report`()

    Print (to `sys.stdout`) a comparison between a and b.

  `report_partial_closure`()

    打印 a 与 b 及共同直接子目录的比较结果。

  `report_full_closure`()

    打印 a 与 b 及共同子目录比较结果（递归地）。

  `dircmp` 类提供了一些有趣的属性，用以得到关于参与比较的目录树的各种信息。

  需要注意，通过 `__getattr__()` 钩子，所有的属性将会惰性求值，因此如果只使用那些计算简便的属性，将不会有速度损失。

  `left`

    目录 a 。

  `right`

    目录 b 。

  `left_list`

    经 hide 和 ignore 过滤，目录 a 中的文件与子目录。

  `right_list`

    经 hide 和 ignore 过滤，目录 b 中的文件与子目录。

  `common`

    同时存在于目录 a 和 b 中的文件和子目录。

  `left_only`

    仅在目录 a 中的文件和子目录。

  `right_only`

    仅在目录 b 中的文件和子目录。

  `common_dirs`

    同时存在于目录 a 和 b 中的子目录。

  `common_files`

    Files in both a and b

  `common_funny`

    在目录 a 和 b 中类型不同的名字，或者那些 `os.stat()` 报告错误的名字。

  `same_files`

    在目录 a 和 b 中，使用类的文件比较操作符判定相等的文件。

  `diff_files`

    在目录 a 和 b 中，根据类的文件比较操作符判定内容不等的文件。

  `funny_files`

    在目录 a 和 b 中无法比较的文件。

  `subdirs`

    一个将 `common_dirs` 中名称映射为 `dircmp` 对象的字典。

下面是一个简单的例子，使用 `subdirs` 属性递归搜索两个目录以显示公共差异文件：

    >>> from filecmp import dircmp
    >>> def print_diff_files(dcmp):
    ...     for name in dcmp.diff_files:
    ...         print "diff_file %s found in %s and %s" % (name, dcmp.left,
    ...               dcmp.right)
    ...     for sub_dcmp in dcmp.subdirs.values():
    ...         print_diff_files(sub_dcmp)
    ...
    >>> dcmp = dircmp('dir1', 'dir2')
    >>> print_diff_files(dcmp)