概要(「読みやすく、壊れにくい」プログラム構造の土台を作る)
プログラム構造の基本は、役割ごとにコードを分けて、入口と出口を明確にし、外部資源(ファイル・フォルダ)を安全に扱い、失敗に備えることです。初心者は「関数で処理を分割」「if name == ‘main‘ で実行入口を定義」「with 文で後片付けを自動化」「例外を絞って受ける」の4本柱をまず身につけましょう。
ファイル操作に強い基本設計(入口・分割・後片付け)
実行入口を明確にする(if name == “main“)
スクリプトとして動かすときの「入口」をここに定義します。テストや再利用時に import しても、勝手に実行されないため安全です。
def main():
# ここに「最上位の流れ」を書く
print("start")
if __name__ == "__main__":
main()
Python関数で「ひと仕事」をまとめる(再利用・テストしやすい)
読み込み、加工、書き出しのような流れは、関数を分けると見通しが劇的に良くなります。引数と戻り値で「何を受け取り、何を返すか」を明確化します。
def load_lines(path: str) -> list[str]:
with open(path, "r", encoding="utf-8") as f:
return [line.rstrip("\n") for line in f]
def transform(xs: list[str]) -> list[str]:
return [x.upper() for x in xs]
def save_lines(path: str, xs: list[str]) -> None:
with open(path, "w", encoding="utf-8", newline="\n") as f:
f.write("\n".join(xs) + "\n")
Pythonwith 文で外部資源の「後片付け」を自動化する
ファイルは開いたら必ず閉じる必要があります。with を使えば、例外が起きても確実に閉じられ、漏れがありません。
from pathlib import Path
def read_text(p: Path) -> str:
with p.open("r", encoding="utf-8") as f:
return f.read()
Python例外を「必要な範囲」にだけ掛ける(握り過ぎない)
想定済みの失敗(存在しない・権限なし)は受け止め、未知の失敗は上位へ伝えます。ユーザー向けの簡潔なメッセージと、開発者向けの詳細ログを分けると運用が楽になります。
def load_safe(path: str) -> str | None:
try:
with open(path, "r", encoding="utf-8") as f:
return f.read()
except FileNotFoundError:
print("ファイルが見つかりません:", path)
return None
Pythonパス・配置・レイアウト(Path を軸に「安全に辿る」)
pathlib.Path を使って「文字列連結を卒業する」
OS差(/ と \)を気にせず、パス結合や作成を直感的に書けます。最初に「プロジェクトの基準パス」を決める習慣をつけましょう。
from pathlib import Path
ROOT = Path(__file__).resolve().parent
DATA = ROOT / "data"
OUT = ROOT / "output"
def ensure_dirs() -> None:
OUT.mkdir(parents=True, exist_ok=True)
Python読み書きのショートカットで簡潔にする
read_text/write_text や read_bytes/write_bytes を活用すると、open の定型を減らせます。エンコーディングは原則 UTF-8 を明示します。
p = DATA / "input.txt"
q = OUT / "result.txt"
text = p.read_text(encoding="utf-8")
q.write_text(text.upper(), encoding="utf-8")
Python設定・ログ・引数(外部化して「差し替えやすく」)
設定は JSON/ENV に外出し(コードと値を分離)
ハードコードすると変更に弱くなります。設定ファイルを読み込み、デフォルト値と上書きの仕組みを用意して柔軟にします。
import json
from pathlib import Path
def load_config(path: Path) -> dict:
if not path.exists():
return {"encoding": "utf-8", "newline": "\n"}
return json.loads(path.read_text(encoding="utf-8"))
Pythonログで「何が起きたか」を残す(標準ライブラリで十分)
print でも良いですが、logging を使うとレベルや出力先の管理が楽です。ファイル操作は外部要因で失敗しやすいため記録が重要です。
import logging
logging.basicConfig(filename="app.log", level=logging.INFO)
def log_started() -> None:
logging.info("app started")
Pythonコマンドライン引数で「入力と出力」を選べるようにする
argparse を使うと、入力ファイルや出力先を起動時に差し替えられます。構造化されたツールへ一歩近づきます。
import argparse
from pathlib import Path
def parse_args() -> tuple[Path, Path]:
ap = argparse.ArgumentParser()
ap.add_argument("--in", dest="inp", type=Path, required=True)
ap.add_argument("--out", dest="out", type=Path, required=True)
a = ap.parse_args()
return a.inp, a.out
Python安全な書き込み・誤上書き対策(成果物を守る)
一時ファイル→置き換えで「原子的」に保存する
途中で落ちても壊れたファイルが残らないように、テンポラリに書いてから置き換えます。重要なレポート・集計で有効です。
import os
from pathlib import Path
def atomic_write(path: Path, data: str) -> None:
tmp = path.with_suffix(path.suffix + ".tmp")
tmp.write_text(data, encoding="utf-8")
os.replace(tmp, path)
Python誤上書きを避けるために「新規のみ」モードを使う
“x” モードで開けば既存なら例外になり、成果物を守れます。ポリシーに沿ったメッセージを出しましょう。
def save_new(path: Path, text: str) -> bool:
try:
with path.open("x", encoding="utf-8", newline="\n") as f:
f.write(text)
return True
except FileExistsError:
print("既存のため作成しません:", path)
return False
Pythonひな形(小さなツールの「実務で通る」構造)
最小でも「入口・引数・処理分割・安全化」を入れる
import argparse
from pathlib import Path
def load_lines(p: Path) -> list[str]:
with p.open("r", encoding="utf-8") as f:
return [line.rstrip("\n") for line in f]
def transform(xs: list[str]) -> list[str]:
return [x.upper() for x in xs]
def save_lines(p: Path, xs: list[str]) -> None:
p.parent.mkdir(parents=True, exist_ok=True)
with p.open("w", encoding="utf-8", newline="\n") as f:
f.write("\n".join(xs) + "\n")
def parse_args() -> tuple[Path, Path]:
ap = argparse.ArgumentParser(description="Uppercase converter")
ap.add_argument("--in", dest="inp", type=Path, required=True)
ap.add_argument("--out", dest="out", type=Path, required=True)
a = ap.parse_args()
return a.inp, a.out
def main() -> None:
inp, out = parse_args()
try:
lines = load_lines(inp)
except FileNotFoundError:
print("入力が見つかりません:", inp)
return
result = transform(lines)
save_lines(out, result)
print("done:", out)
if __name__ == "__main__":
main()
Pythonこの構造なら、入口が明確で、関数に分割され、例外で失敗を伝え、フォルダを自動作成し、改行とエンコーディングを明示して安定します。小さいのに「現場で通る」品質に近づきます。
まとめ
プログラム構造の基本は、入口の明確化(if name == “main“)、関数分割で見通しと再利用性を高め、with 文で後片付けを自動化し、例外を必要十分に扱うこと。パスは pathlib.Path を使い、プロジェクトの基準パスから辿る。設定・ログ・引数を外部化して差し替えやすくし、書き込みは原子的保存や新規作成モードで成果物を守る。まずはこの型(ひな形)を真似し、あなたの処理を中に差し替えていけば、初心者でも短いコードで、安定して運用できるファイル操作プログラムを作れます。
