# 10.5. `filecmp` --- ファイルおよびディレクトリの比較

ソースコード: Lib/filecmp.py

`filecmp` モジュールでは、ファイルおよびディレクトリを比較するため、様々な時間／正確性のトレードオフに関するオプションを備えた関数を定義しています。ファイルの比較については、 `difflib` モジュールも参照してください。

`filecmp` モジュールでは以下の関数を定義しています:

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

  名前が f1 および f2 のファイルを比較し、二つのファイルが同じらしければ `True` を返し、そうでなければ `False` を返します。

  shallow が真の場合、同一の `os.stat()` シグニチャを持つファイルは等しいとみなされます。

  `os.stat()` シグニチャが変わらない限り、この関数を用いて比較されたファイルが再び比較されることはありません。

  可搬性と効率のために、この関数は外部プログラムを一切呼び出さないので注意してください。

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

  dir1 と dir2 ディレクトリの中の、common で指定されたファイルを比較します。

  ファイル名からなる3つのリスト: 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'` はそれぞれ、返される3つのリストのいずれかに登録されます。

例:

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

## 10.5.1. `dircmp` クラス

`dircmp` インスタンスはこのコンストラクタを用いて構築されます:

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

  ディレクトリ a および b を比較するための新しいディレクトリ比較オブジェクトを生成します。 ignore は比較の際に無視するファイル名のリストで、標準の設定では `['RCS', 'CVS', 'tags']` です。 hide は表示しない名前のリストで、標準の設定では `[os.curdir, os.pardir]` です。

  `dircmp` クラスは、 `filecmp.cmp()` で説明されているような 浅い 比較を行うことによりファイルを比較します。

  `dircmp` クラスは以下のメソッドを提供しています:

  `report`()

    a と b の比較を (`sys.stdout` に) 表示します。

  `report_partial_closure`()

    a および b およびそれらの直下にある共通のサブディレクトリ間での比較結果を出力します。

  `report_full_closure`()

    a および b およびそれらの共通のサブディレクトリ間での比較結果を (再帰的に比較して) 出力します。

  `dircmp` クラスは、比較されているディレクトリ階層に関する様々な情報のビットを得るために使用することのできる、興味深い属性を数多く提供しています。

  `__getattr__()` フックを経由すると、全ての属性をのろのろと計算するため、速度上のペナルティを受けないのは計算処理の軽い属性を使ったときだけなので注意してください。

  `left`

    ディレクトリ a です。

  `right`

    ディレクトリ b です。

  `left_list`

    a にあるファイルおよびサブディレクトリです。hide および ignore でフィルタされています。

  `right_list`

    b にあるファイルおよびサブディレクトリです。hide および ignore でフィルタされています。

  `common`

    a および b の両方にあるファイルおよびサブディレクトリです。

  `left_only`

    a だけにあるファイルおよびサブディレクトリです。

  `right_only`

    b だけにあるファイルおよびサブディレクトリです。

  `common_dirs`

    a および b の両方にあるサブディレクトリです。

  `common_files`

    a および b の両方にあるファイルです。

  `common_funny`

    a および b の両方にあり、ディレクトリ間でタイプが異なるか、 `os.stat()` がエラーを報告するような名前です。

  `same_files`

    クラスのファイル比較オペレータを用いて a と b の両方において同一のファイルです。

  `diff_files`

    a と b の両方に存在し、クラスのファイル比較オペレータに基づいて内容が異なるファイルです。

  `funny_files`

    a および b 両方にあるが、比較されなかったファイルです。

  `subdirs`

    `common_dirs` のファイル名を `dircmp` オブジェクトに対応付けた辞書です。

これは `subdirs` 属性を使用して 2 つのディレクトリを再帰的に探索して、共通の異なるファイルを示すための単純化された例です:

    >>> 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)