Pythonによるディレクトリの作成と削除

今回は、Pythonでファイルシステムを操作するシリーズの続きです。前回の記事では、ファイルの読み込みと書き込みを扱いました。興味深いことに、ファイルシステムは、データをディスクに保存/取得する方法以上のものです。ファイル、ディレクトリ、ソケット(プロセス間通信用)、名前付きパイプ、ソフトリンクとハードリンク、さらに特殊ファイル(ブロックデバイス)など、他にもさまざまな種類の項目があります。これらへの読み書きは、これまでの記事で見てきたのと同様の方法で行われます。

今回は、ディレクトリの扱いに焦点を当てます。UNIX/Linuxのような他のオペレーティングシステムでは、代わりに別の用語を使用し、「エントリ」は「フォルダ」と名付けられています。次に、現在の作業ディレクトリを特定する方法、永続的なディレクトリと一時的な単一のディレクトリ、およびサブフォルダーを含むネストしたディレクトリ構造の作成方法、および不要になったディレクトリを削除する方法を紹介します。そのため、2つのPythonモジュール ostempfile が登場します。

必要なPythonモジュール

ファイルの読み書きには追加のモジュールは必要ありませんが、ファイルシステムの機能(ディレクトリを扱うなど)にアクセスするには、別のモジュールを使用する必要があります。まず、os モジュールをロードする必要がある。os` は Python のモジュールで、Python のエコシステムのコア部分に属しています。読み込みは以下のようにimport文を使って行います。

import os


osモジュールは、この記事で必要となるメソッドのほとんどを含んでいます。しかし、後で説明するように、データを保存するための一時ファイルを作成するなど、より高度なことをしたい場合は、tempfile` モジュールも必要になります。

現在の作業ディレクトリを検出する

ディレクトリの作成/削除を行う前に、getcwd() メソッドを用いて現在の作業ディレクトリを検出するなど、他の基本的なディレクトリ操作を行う方法を見てみましょう。このメソッドは、作業ディレクトリのパスを含む文字列を返します。リスト1は、このメソッドをPythonスクリプトに組み込む方法を示しています。

# import the os module
import os


# detect the current working directory and print it
path = os.getcwd()
print ("The current working directory is %s" % path)


リスト1

出力はこのようになるはずです。

$ python3 cwd.py
The current working directory is /home/frank/


さらに、osモジュールには getcwdb() メソッドが追加されています。このメソッドは getcwd() メソッドと似ていますが、代わりにバイナリ文字列としてパスを返します。

ファイルやディレクトリが存在するかどうかをチェックするような、この記事でカバーされていない他のディレクトリ操作がかなりあります。しかし、今はこの記事の主目的のために移動します。

ディレクトリの作成

一つのディレクトリを作成するには、mkdir() メソッドを使用します。パラメータとして、mkdir() はディレクトリを作成するためのパス名を最初に要求します。例として、以下のコードを参照してください。

import os


# define the name of the directory to be created
path = "/tmp/year"


try:
    os.mkdir(path)
except OSError:
    print ("Creation of the directory %s failed" % path)
else:
    print ("Successfully created the directory %s " % path)


リスト2

mkdir()メソッドは、一度の呼び出しで1つ以上の深いレベルのサブディレクトリを作成することができないことに留意してください。パス全体を作成するには、ディレクトリレベルごとにmkdir()を一回ずつ呼び出す必要があります。また、複数のディレクトリを一度に作成したい場合は、代わりにmakedirs()` メソッドを利用します (以下のリスト 4 を参照してください)。

オプションのパラメータとして、mkdir()の呼び出しの中で、ディレクトリに対するアクセス権を指定することができます。デフォルトは777で、オーナー、グループメンバー、その他すべてのユーザーが読み書き可能な状態になっています。755のように,より限定的な設定(すべてのユーザーが読み書きができ,所有者だけが書き込みができる)が必要な場合は,以下のように呼び出すことができます.

import os


# define the name of the directory to be created
path = "/tmp/year"


# define the access rights
access_rights = 0o755


try:
    os.mkdir(path, access_rights)
except OSError:
    print ("Creation of the directory %s failed" % path)
else:
    print ("Successfully created the directory %s" % path)


リスト3

このコードで注意すべき点は、アクセス権(ここでは755)が8進数のプレフィックス(0o)を使って指定されていることに気づいたかもしれませんが、これは数字を最初に10進数に変換する必要がないようにするためです。OSはアクセス権を8進数で表現しているので、ここでもそのように表現します。

しかし、Pythonのドキュメントにあるように、システムによっては mode パラメータを無視するので、代わりに os.chmod を使用する必要があります。

サブディレクトリを含むディレクトリの作成

既に述べたように、mkdir() メソッドは単一のディレクトリを作成することしかできません。複数レベルのサブディレクトリを作成するには、 makedirs() メソッドの出番となります。実際、makedirs()は、mkdir()を呼び出して、次々とディレクトリを作成するように実装されています。

makedirs()はパラメータとして、作成するパス全体を受け取ります。この方法は、UNIX/Linuxのコマンドmkdir -p` に似ています。リスト4は、このメソッドの使い方の例です。

import os


# define the name of the directory to be created
path = "/tmp/year/month/week/day"


try:
    os.makedirs(path)
except OSError:
    print ("Creation of the directory %s failed" % path)
else:
    print ("Successfully created the directory %s" % path)


リスト3

一時ディレクトリの作成

これまで、ファイルシステムに恒久的なエントリを作成してきました。データを一時的に保存するなどのさまざまな理由から、一時的なディレクトリを持つことが必要になることがあります。tempfile` モジュールは、このようなケースを安全かつ一貫した方法で処理するメソッドを含んでいます。

リスト5は、 TemporaryDirectory() メソッドと with ステートメントを組み合わせて使用する例を示しています。with` 文の後では、ディレクトリとそのコンテンツの両方が完全に削除されているため、一時ディレクトリはもう存在しません。

import tempfile


# create a temporary directory
with tempfile.TemporaryDirectory() as directory:
    print('The created temporary directory is %s' % directory)


# directory and its contents have been removed by this point


リスト5

リスト6は、リスト5のPythonスクリプトの出力です。UNIX/Linuxシステムでは、一時ファイルを作成するために、/tmp、/var/tmp、/usr/tmpの3つのディレクトリを試し、その中で最初に一致したものを使用します。今回のケースでは、/tmpディレクトリが使用されます。

$ python3 mkdir-temporary.py
The created temporary directory is /tmp/tmpf6o0hy3c


リスト6

ディレクトリの削除

ディレクトリの削除は、ディレクトリを作成する場合と逆のケースです。これは os モジュールの rmdir() メソッドを使用して行うことができます。rmdir() はディレクトリ名を含むパス文字列を必要とし、パス文字列の最も深いエントリーのみを削除します。このメソッドは、ディレクトリが完全に空のときのみ動作することに注意してください。もし、空でない場合は OSError が発生します。リスト7は、それに従ったPythonのコードです。

import os


# define the name of the directory to be deleted
path = "/tmp/year"


try:
    os.rmdir(path)
except OSError:
    print ("Deletion of the directory %s failed" % path)
else:
    print ("Successfully deleted the directory %s" % path)


リスト7

ディレクトリツリー全体を削除したい場合は、shutilモジュールの rmtree() メソッドがその作業を手助けしてくれます。

結論

お気づきのように、Pythonではディレクトリの扱いがとてもシンプルです。この種のファイルエントリを作成したり削除したりするのに必要なのは、ほんの数行のコードだけです。

リンクと参考文献

  • The Linux Documentation project (TLDP), Linuxのファイルシステムに関する一般的な概要。

ファイルシステム、ファイル

謝辞

Zoleka Hatitongweのサポートに感謝する。

タイトルとURLをコピーしました