サイトアイコン ITC Media

【コード付】PythonのOSモジュールでできることを徹底解説

programming

(最終更新日:2023年6月)

✔本記事はこのような方に特におすすめ

「OS Pythonってどんな機能があるんだろう?」
「OS Pythonの使い方やコードを知りたい」
「OS Pythonに関する実践例を見てみたい」

✔本記事でお伝えする内容

当記事では、OS Pythonの基本から応用まで、具体例を交えてわかりやすく解説します。

ぜひ最後までご覧ください。

筆者プロフィール

【現職】プロダクトマネージャー

【副業】ブログ(月間20万PV)/YouTube/Web・アプリ制作

「プログラミング × ライティング × 営業」の経験を活かし、30後半からのIT系職へシフト。現在はプロダクトマネージャーとして、さまざまな関係者の間に入り奮闘してます。当サイトでは、実際に手を動かせるWebアプリの開発を通じて、プログラミングはもちろん、IT職に必要な情報を提供していきます。

【当ブログで紹介しているサイト】

当サイトチュートリアルで作成したデモ版日報アプリ

Django × Reactで開発したツール系Webアプリ

✔人に見せても恥ずかしくないコードを書こう

「リーダブルコード」は、わかりやすく良いコードの定義を教えてくれる本です。

  • 見るからにきれいなコードの書き方
  • コードの分割方法
  • 変数や関数の命名規則

エンジニアのスタンダートとすべき基準を一から解説しています。

何回も読むのに値する本なので、ぜひ手にとって読んでみてください。

はじめに: osモジュールの意義と概要

こちらでは、Pythonの標準ライブラリであるosモジュールの意義と概要についてお伝えします。

osモジュールについて理解することで、Pythonのポータビリティと機能性がどのように強化されるのかを把握しましょう。

osモジュールとは?

osモジュールはPythonの標準ライブラリであり、オペレーティングシステム(OS)とのインターフェースを提供します。

Pythonで、以下のようなOSレベルの操作が直接おこなえるモジュールです。

Pythonのコードがさまざまなプラットフォームで実行できるようになり、ポータビリティが向上します。

ファイル名、コマンドライン引数、および環境変数

osモジュールは、基本的なOSレベルの操作をサポートします。

import os

# ファイル名の操作
path = os.path.join("dir", "file.txt")  # ファイルパスの結合
print(path)  # 出力: dir/file.txt

dirname = os.path.dirname(path)  # ディレクトリ名の取得
basename = os.path.basename(path)  # ファイル名の取得
print(dirname)  # 出力: dir
print(basename)  # 出力: file.txt

# コマンドライン引数の取得
args = os.sys.argv[1:]  # 最初の引数はスクリプト名なので除外
print(args)  # 出力: コマンドライン引数のリスト

# 環境変数の操作
os.environ["MY_VARIABLE"] = "my_value"  # 環境変数の設定
value = os.environ.get("MY_VARIABLE")  # 環境変数の取得
print(value)  # 出力: my_value

PythonとUTF-8モード

Python3.7以降では、osモジュールにUTF-8モードが追加されました。

この機能を使うと、ファイル名や環境変数などのシステムのエンコードに依存する部分をすべてUTF-8で扱えます。

異なるロケール設定を持つシステム間でも文字列の扱いが一定になり、予期しないエンコードエラーを避けられるでしょう。

import os

# ファイル名の操作
path = os.path.join("ディレクトリ", "ファイル.txt")  # UTF-8エンコードされたファイルパスの結合
print(path)  # 出力: ディレクトリ/ファイル.txt

dirname = os.path.dirname(path)  # ディレクトリ名の取得
basename = os.path.basename(path)  # ファイル名の取得
print(dirname)  # 出力: ディレクトリ
print(basename)  # 出力: ファイル.txt

# 環境変数の操作
os.environ["MY_VARIABLE"] = "値"  # UTF-8エンコードされた環境変数の設定
value = os.environ.get("MY_VARIABLE")  # 環境変数の取得
print(value)  # 出力: 値

プロセスのパラメーター関連操作

osモジュールでは、Pythonの実行しているプロセスに関連するパラメーターの操作が可能。

これらの機能は、システムレベルのタスクを扱う際に非常に便利です。

ファイル操作

ここでは、osモジュールを使ってPythonでどのようにファイル操作を行うかについてお伝えします。

ファイルオブジェクトの生成

osモジュールのos.open()関数を使って、新しいファイルオブジェクトを生成できます。

os.open()関数は、ファイル名とフラグをパラメータとして取り、新しく開いたファイルのファイル記述子を返すものです。

フラグには、読み取り、書き込み、追加などのモードを指定できます。

import os

# 新しいファイルを書き込みモードで開く
file_descriptor = os.open("new_file.txt", os.O_WRONLY | os.O_CREAT)

# ファイルにデータを書き込む
os.write(file_descriptor, b"This is some text.")

# ファイルを閉じる
os.close(file_descriptor)

ファイル記述子

ファイル記述子は、オープンしたファイルを操作するための整数値で、OSが管理するもの。

osモジュールは、これを利用してファイルへの読み書きや、ファイルのメタデータへのアクセスなどを提供します。

import os

# ファイルを読み込みモードで開く
file_descriptor = os.open("data.txt", os.O_RDONLY)

# ファイルからデータを読み取る
data = os.read(file_descriptor, 1024)

# 読み取ったデータを表示
print(data.decode())

# ファイルを書き込みモードで開く
file_descriptor = os.open("output.txt", os.O_WRONLY | os.O_CREAT)

# ファイルにデータを書き込む
os.write(file_descriptor, b"This is some text.")

# ファイルを閉じる
os.close(file_descriptor)

ファイル記述子とバイト数を引数に取り、それぞれファイルからの読み取りや書き込みをおこなうのです。

os.rename():ファイル名の変更

os.rename()関数を使うと、既存のファイル名やディレクトリ名を変更できます。

この関数では、2つの引数(現在のファイル名と新しいファイル名)を設定してください。

新しい名前が既に存在する場合、そのファイルは上書きされます。

import os

# 現在のファイル名
current_file_name = "old_file.txt"

# 新しいファイル名
new_file_name = "new_file.txt"

# ファイル名を変更する
os.rename(current_file_name, new_file_name)

os.remove():ファイルの削除 (continued)

os.remove()関数は、指定したパスのファイルを削除するもの。

削除する対象がディレクトリの場合、IsADirectoryErrorの例外が発生します。

ディレクトリを削除する際にはos.rmdir()関数を使用しましょう。

import os

# 削除するファイルのパス
file_path = "path/to/file.txt"

try:
    # ファイルを削除する
    os.remove(file_path)
    print("ファイルの削除に成功しました。")
except FileNotFoundError:
    print("指定したファイルが見つかりません。")
except IsADirectoryError:
    print("指定したパスはディレクトリです。ファイルの削除ではありません。")
except Exception as e:
    print("ファイルの削除中にエラーが発生しました:", str(e))

ディレクトリ操作

次に、osモジュールを使用したディレクトリ操作について説明します。

os.walk():ディレクトリリスト処理

os.walk()関数は、指定したディレクトリをトップダウンまたはボトムアップで走査して、ディレクトリ名とファイル名のリストを生成するものです。

ディレクトリのツリー構造を再帰的に走査する際に非常に便利。

関数は3つの値ををyieldします。

import os

# トップダウンで指定したディレクトリを走査する
def traverse_directory(top_directory):
    for dirpath, dirnames, filenames in os.walk(top_directory):
        print(f"ディレクトリ: {dirpath}")
        print(f"サブディレクトリ: {dirnames}")
        print(f"ファイル: {filenames}")
        print()

# ディレクトリを走査する
directory_path = "path/to/directory"
traverse_directory(directory_path)

os.listdir():ディレクトリのリスト表示

os.listdir()関数は、指定したディレクトリ内の全ファイルとサブディレクトリの名前をリストとして返すもの。

結果はソートされず、アルファベット順に並んでいるとは限りません。

また、”.”や”..”などの特殊なディレクトリは含まれないことも頭に入れておきましょう。

import os

# 指定したディレクトリ内のファイルとサブディレクトリの名前を表示する
def list_directory_contents(directory):
    contents = os.listdir(directory)
    for item in contents:
        print(item)

# ディレクトリのパスを指定して実行する
directory_path = "path/to/directory"
list_directory_contents(directory_path)

os.mkdir():ディレクトリの作成

os.mkdir()は、指定した名前の新しいディレクトリを作成する関数です。

デフォルトのアクセス権は777で、これはumask値によって修正されます。

すでに同名のディレクトリまたはファイルが存在する場合は、FileExistsErrorが発生。

ディレクトリのネストした作成は、os.makedirs()関数を使用してください。

import os

# 単一のディレクトリを作成する
def create_directory(directory_name):
    try:
        os.mkdir(directory_name)
        print(f"Directory '{directory_name}' created successfully.")
    except FileExistsError:
        print(f"Directory '{directory_name}' already exists.")

# ネストしたディレクトリを作成する
def create_nested_directory(directory_path):
    try:
        os.makedirs(directory_path)
        print(f"Directory '{directory_path}' created successfully.")
    except FileExistsError:
        print(f"Directory '{directory_path}' already exists.")

# 単一のディレクトリを作成する例
directory_name = "new_directory"
create_directory(directory_name)

# ネストしたディレクトリを作成する例
nested_directory_path = "parent_directory/child_directory"
create_nested_directory(nested_directory_path)

os.path():パス操作の基本機能

os.pathは、ファイルやディレクトリパスに関する操作を提供するサブモジュールです。

このモジュールを利用して、以下のようなことができます。

OSに依存しないパス操作が可能となり、コードの移植性を保てます。

import os

# パスの結合
path1 = "path/to"
path2 = "file.txt"
joined_path = os.path.join(path1, path2)
print(joined_path)  # 出力: path/to/file.txt

# パスの分割
path = "/path/to/file.txt"
dir_name, file_name = os.path.split(path)
print(dir_name)  # 出力: /path/to
print(file_name)  # 出力: file.txt

# パスの存在確認
file_path = "path/to/file.txt"
exists = os.path.exists(file_path)
print(exists)  # 出力: True (もしくは False)

# 絶対パスへの変換
relative_path = "path/to/file.txt"
absolute_path = os.path.abspath(relative_path)
print(absolute_path)  # 出力: /current/working/directory/path/to/file.txt

osモジュールの応用機能

次に、osモジュールが提供するさまざまな応用機能について解説します。

環境変数操作

osモジュールを利用すると、Pythonプログラムから環境変数を操作することが可能です。

具体的にはos.environオブジェクトを通じて環境変数を取得、設定したり、os.getenv()、os.putenv()などの関数を使って環境変数の値を得たり、設定したりすることができます。

import os

# 環境変数の取得
home_dir = os.environ.get("HOME")
print(home_dir)  # 出力: ホームディレクトリのパス (もしくは None)

# 環境変数の設定
os.environ["MY_VARIABLE"] = "my_value"

# 環境変数の値の取得
my_variable = os.getenv("MY_VARIABLE")
print(my_variable)  # 出力: my_value (もしくは None)

# 環境変数の一覧表示
env_variables = os.environ
for key, value in env_variables.items():
    print(f"{key}={value}")

プロセス管理

osモジュールでは、新たなプロセスを生成したり、プロセスのIDを取得したりも可能です。

import os

# シェルコマンドを実行する
os.system("ls -l")

# 現在のプロセスIDを取得する
pid = os.getpid()
print(f"Current process ID: {pid}")

スケジューラーへのインターフェイス

osモジュールには、スケジューラーへのインターフェイスが含まれています。

スケジューリングの優先度を設定したり、プロセスを一時停止したりすることが可能です。

import os
import time

# プロセスのスケジューリング優先度を増減させる
os.nice(10)  # スケジューリング優先度を増加させる
os.nice(-5)  # スケジューリング優先度を減少させる

# プロセスを一時停止させる
print("Before sleep")
time.sleep(5)  # 5秒間プロセスを一時停止
print("After sleep")

乱数生成

osモジュールを使うと、乱数の生成も可能です。

os.urandom()関数を使用すると、指定されたバイト数のランダムなバイト列を生成します。

これは暗号学的なランダム性が求められる場面で利用できます。

乱数はソフトウェアの動作を予測不可能にするため、セキュリティの観点から重要な役割を果たすのです。

import os

# 指定されたバイト数のランダムなバイト列を生成
random_bytes = os.urandom(10)
print(random_bytes)

# バイト列を整数に変換して乱数を生成
random_number = int.from_bytes(random_bytes, byteorder="big")
print(random_number)

osモジュールを使った具体的な実例

osモジュールの理解を深めるために、具体的な実例を通じてその使用方法を説明します。

ターミナルのサイズの問い合わせ

osモジュールを利用すれば、ターミナル(コンソール)のサイズを問い合わせることも可能です。

os.get_terminal_size()関数を使用すると、現在のターミナルのサイズを取得できます。

ターミナルの横幅に合わせて出力を整形するなど、ユーザーエクスペリエンスを向上させれる関数です。

import os

# ターミナルのサイズを取得
terminal_size = os.get_terminal_size()

# ターミナルの横幅と縦幅を表示
print("Terminal size: {} columns x {} rows".format(terminal_size.columns, terminal_size.rows))

ファイル記述子の継承

osモジュールはファイル記述子の継承を扱う機能も提供します。

子プロセスに対して親プロセスのファイル記述子を継承させることが可能です。

具体的には、os.fork()で新たなプロセスを生成した際に、親プロセスのファイル記述子が子プロセスに引き継がれます。

これにより、親プロセスと子プロセスが同じファイルにアクセスできるのです。

import os

# ファイルを開く
file = open("example.txt", "w")
file.write("Hello, World!")
file.close()

# 新しいプロセスを生成
pid = os.fork()

if pid == 0:
    # 子プロセスの処理
    print("Child process")
    file = open("example.txt", "r")
    content = file.read()
    print("Content read by child process:", content)
    file.close()
else:
    # 親プロセスの処理
    print("Parent process")
    file = open("example.txt", "r")
    content = file.read()
    print("Content read by parent process:", content)
    file.close()

Linux拡張属性とosモジュール

osモジュールを使うと、Linuxの拡張属性という概念も操作できます。

拡張属性はファイルやディレクトリに関連付けられる追加情報で、os.setxattr()やos.getxattr()などの関数を使って操作可能です。

ファイルやディレクトリに対して追加のメタデータを保存することが可能になります。

import os

# 拡張属性を設定する関数
def set_extended_attribute(path, attribute_name, attribute_value):
    os.setxattr(path, attribute_name, attribute_value)

# 拡張属性を取得する関数
def get_extended_attribute(path, attribute_name):
    attribute_value = os.getxattr(path, attribute_name)
    return attribute_value

# ファイルに拡張属性を設定する
file_path = "example.txt"
attribute_name = "user.description"
attribute_value = "This is a file with extended attribute."
set_extended_attribute(file_path, attribute_name, attribute_value)

# ファイルから拡張属性を取得する
retrieved_attribute_value = get_extended_attribute(file_path, attribute_name)
print("Extended attribute value:", retrieved_attribute_value)

まとめ

当記事では、今回お伝えしたosモジュールの機能とその利用方法について学びました。

Pythonのosモジュールは強力であり、さまざまな用途に対応する機能を提供しています。

これらの機能を理解し、適切に利用することで、プログラムの効率性と表現力を高めましょう。

さらに深い理解を得たい方は、当サイトのPythonセクションでさまざまなコードを真似しながら、手を動かしてみてください。

これらの知識がPythonでの開発作業に役立つことを願っています。

モバイルバージョンを終了