こんにちは、くのへです。
ここから、日常作業が楽になる「Pythonデスクトップ簡易アプリ10選」を投稿していきます。
しかも、このアプリを開発を通して、Pythonのライブラリなどを勉強して習得してしまおう!という企画です。
是非、一緒に楽しんで走って頂きたいと思います。
また、CursorやVScode(GitHubCopilot)を使っている方は、生成AIに作って貰ったはいいけど、コードが全然わからない!!ということもあろうと思います。
その方も、この記事でライブラリを習得すると、コードが読めるようになるんじゃないかな、と思います!
なお、デスクトップで.pyや.pywを動かす設定や、生成AI CursorでPythonを使う設定については、この↓動画をご参照ください
作成する内容とコード
今回作成するプログラムは2つです。次のようなプログラムです
◆yyyymmdd形式の空のフォルダを作成する
①.pyまたは.pywをダブルクリックすると、デスクトップにyyyymmdd形式の日付を名前としたフォルダを生成する
②もしも既に同名フォルダがある場合は、yyyymmdd(1)のように通し番号を付ける
◆yyyymmdd形式のフォルダ+そのフォルダ内に(旧版)(参考資料)のサブフォルダも作成する
①.pyまたは.pywをダブルクリックすると、デスクトップにyyyymmdd形式の日付を名前としたフォルダを生成する
②もしも既に同名フォルダがある場合は、yyyymmdd(1)のように通し番号を付ける
③そのフォルダ内には(旧版)(参考資料)のサブフォルダも作成する
コード
コピペで動くと思います(Python3をインストールの上、ファイル拡張子は.pyか.pywで実行下さい)
◆yyyymmdd形式の空のフォルダを作成する
import os
import datetime
today = datetime.date.today()
date_str = today.strftime("%Y%m%d")
desktop_path = os.path.expanduser("~/Desktop")
folder_name = date_str
folder_path = os.path.join(desktop_path, folder_name)
counter = 1
while os.path.exists(folder_path):
folder_name = f"{date_str}({counter})"
folder_path = os.path.join(desktop_path, folder_name)
counter += 1
os.makedirs(folder_path)
◆yyyymmdd形式のフォルダ+そのフォルダ内に(旧版)(参考資料)のサブフォルダも作成する
import os
import datetime
today = datetime.date.today()
date_str = today.strftime("%Y%m%d")
desktop_path = os.path.expanduser("~/Desktop")
folder_name = date_str
folder_path = os.path.join(desktop_path, folder_name)
counter = 1
while os.path.exists(folder_path):
folder_name = f"{date_str}({counter})"
folder_path = os.path.join(desktop_path, folder_name)
counter += 1
os.makedirs(folder_path)
subfolders = ["(旧版)", "(参考資料)"]
for subfolder in subfolders:
subfolder_path = os.path.join(folder_path, subfolder)
os.makedirs(subfolder_path)
解説
osライブラリ
osライブラリは何回も使っていますね。
出てくる順に解説します。
◆os.path.expanduser(“~”)
desktop_path = os.path.expanduser("~/Desktop")
ここは、初めての方は呪文のようなものだと思えばOKだと思います。
expanduserは「エクスパンド ユーザー」と読みます。「expand user」ですね。エクスパウンデューザーとは読みません。
os.path.expanduser(“~”)で現在のユーザのホームディレクトリのパスを返します。そういうものだと思ってください。
ホームディレクトリというのはWindowsでいう所の「C:\Users\ユーザー名」のフォルダことです。
デスクトップはホームディレクトリの中にありますので、os.path.expanduser(“~/Desktop”)と書くと、デスクトップになるわけです。
◆os.path.join
folder_path = os.path.join(desktop_path, folder_name)
デスクトップパス、フォルダ名、ファイル名を適切に結合して、完全なファイルパスを作成します。
カンマで区切ったパスやファイル名を繋いでくれます。
上記の例でいえば、デスクトップパス「C:\Users\ユーザー名」とフォルダ名「20250114」を繋いで「C:\Users\ユーザー名\20250114」というパスにできます。
なお、ここは敢えてos.path.joinを使わず
folder_path = desktop_path + “/” + folder_name
でも動作します。
◆os.path.exists
while os.path.exists(folder_path):
folder_name = f"{date_str}({counter})"
folder_path = os.path.join(desktop_path, folder_name)
counter += 1
os.path.exists(アドレス)と書くと、そのアドレスのファイルもしくはフォルダが既に存在しているかどうかを判定出来ます。
もしも存在したらTrue、存在しなければFalseが返されます。
while文と組み合わせることで、同名フォルダが生じることを回避できるまで、変数counterの数字を増やしてfolder_nameとfolder_pathを書き換えてくれるコードの出来上がりです。
なお、「f “文字列”」という表現を初めてみた方もいるかと思います。
これはf-ストリングという書き方で、文字列の中に変数を埋め込めます。
埋め込むためには変数を波カッコ{}で囲います。
ということで下記は等価です。
(なおdate_strという文字列型にcounterという数値型を混ぜるとエラーが出るので、str関数でcounterを文字列かしています)
f"{date_str}({counter})"
date_str + "(" + str(counter) + ")"
どっちが読みやすい・書きやすいは人によりますが、今回のような()を使う際や、文字列型と数値型の変数を混ぜた文字列を作る場合はf-ストリングの書き方がスマートに見えますね。
◆os.makedirs
os.makedirs(folder_path)
これは見れば直感的に分かりますね。
フォルダを作る命令です。
os.makedirs(パス)と書くことで、そのパスのフォルダを作成します。
今日は2つコードを作りましたが、結局makedirsを使ってサブフォルダを作っているだけですので、os.makedirsを1つ目のコードで理解できていたら2つ目のコードは簡単ですね。
なお、今日のコードでは出てきませんでしたが、次のように第2引数にexist_ok=Trueと書くと、そのフォルダがあった場合には何もせず、フォルダが無い時にはフォルダを作成する、というコードになります。
これも是非合わせて覚えましょう!
os.makedirs(folder_path, exist_ok=True)
◆その他に覚えておいた方が良い内容
今回のコードでは出てこなかったのですが、次のように直接絶対パスを書くという案もあります。
os.makedirs(“C:\Users\masaz\Documents” + “/” + folder_name)
しかし実はこれはエラーになります。
このコードのバックスラッシュ(\)がエスケープシーケンスであるため、上手く動かないんです。
回避するためには次のようにバックスラッシュを2重にするという手段があります。
os.makedirs(“C:\\Users\\masaz\\Documents” + “/” + folder_name)
でもこれも超めんどくさいです。
そこで、r文字列(row文字列、rストリングともいう)を使いましょう。
r文字列の使い方は簡単!!
“文字列” ⇒ r”文字列” というように、文字列のクオーテーションの前にrを添えるだけです。
os.makedirs("C:\Users\masaz\Documents" + "/" + folder_name)
↓
os.makedirs(r"C:\Users\masaz\Documents" +"/" + folder_name)
この「r文字列」は「文字列の中のエスケープシーケンスを無視する」という意味になります。
よって、エスケープシーケンスが効かなくなり、ちゃんとパスを表現していることになります。
(補足説明)
ちなみに、pythonはフォルダ階層構造を示すのに、バックスラッシュ(\)でもスラッシュ(/)でもどちらでも大丈夫なようになっています。
ちなみに、上記の通りr文字列は文字列の中のエスケープシーケンスを無効にしてくれますが、なんと、最後にバックスラッシュを設けることは許容されていません(なぜ、、、、)
そのため、↓こう書くとエラーになります。何なんだこの仕様は、、、
os.makedirs(r”C:\Users\masaz\Documents\” + folder_name)
datetimeライブラリ
datetimeライブラリは次の部分で使っていますね。
today = datetime.date.today()
date_str = today.strftime("%Y%m%d")
datetimeはその名の通り、Python で日付と時刻を扱うための標準ライブラリです。このライブラリを使うことで、日付や時刻の表現、計算、フォーマット変換など、さまざまな操作を簡単に行うことができます。
例えば、datetime.date.today
具体的には、以下のような機能があります。使う際には「datetime.メソッド/属性」と書いて使います(使用例を参照)。
クラス | メソッド/属性 | 説明 | 使用例(コード) |
---|---|---|---|
datetime | datetime.now() | 現在の日付と時刻を取得 | datetime.datetime.now() → 2025-01-14 10:30:00 |
datetime | datetime.today() | 現在の日付を取得(now()と同じ) | datetime.datetime.today() → 2025-01-14 10:30:00 |
datetime | datetime.strptime() | 文字列を指定フォーマットでdatetimeオブジェクトに変換 | datetime.datetime.strptime(‘2025-01-14’, ‘%Y-%m-%d’) |
datetime | datetime.strftime() | datetimeオブジェクトを文字列にフォーマット | datetime.datetime.now().strftime(‘%Y/%m/%d’) → 2025/01/14 |
datetime | datetime(年, 月, 日, 時, 分, 秒) | 特定の日付を表すdatetimeオブジェクトを生成 | d=datetime.datetime(2025, 1, 14, 10, 30) d.year → 2025 |
date | date.today() | 今日の日付を取得 | datetime.date.today() → 2025-01-14 |
date | date(年, 月, 日) | 特定の日付を表すdateオブジェクトを生成 | datetime.date(2025, 1, 14) |
date | .year .month .day | 年、月、日を取得 | d = datetime.date(2025, 1, 14) d.year → 2025 |
time | time(時, 分, 秒, ミリ秒) | 特定の時刻を表すtimeオブジェクトを生成 | datetime.time(10, 30, 0) → 10:30:00 |
time | .hour .minute .second | 時、分、秒を取得 | t = datetime.time(10, 30, 0) t.hour → 10 |
上記のdatetime.strftime()のカッコの中には、次のような書式指定子を入力すると、期待する値を作ることが出来ます。
今回はyyyymmdd形式の文字列が欲しかったので、「%Y%m%d」という文字をカッコ内に入れればいいわけですね。
ただし文字列として入力する必要があるので、シングルクオートもしくはダブルクオートで囲む必要があります。
→datetime.strftime(“%Y%m%d”)
書式指定子 | 説明 | 例 |
---|---|---|
%Y | 4桁の西暦 | 2023 |
%y | 2桁の西暦 | 23 |
%m | 2桁の月 (01-12) | 08 |
%B | 月のフルネーム (例: January) | August |
%b | 月の省略名 (例: Jan) | Aug |
%d | 2桁の日 (01-31) | 15 |
%H | 24時間形式の時 (00-23) | 14 |
%I | 12時間形式の時 (01-12) | 02 |
%M | 2桁の分 (00-59) | 30 |
%S | 2桁の秒 (00-59) | 45 |
%p | AM または PM | PM |
%a | 曜日の省略名 (例: Mon) | Tue |
%A | 曜日のフルネーム (例: Monday) | Tuesday |
%w | 曜日 (0-6, 日曜日が0) | 2 |
%j | 年の通算日 (001-366) | 227 |
これ以外にも指定出来るものがありますが、あまり使わないと思います。
生成AIに聞くと詳しく教えてくれますので、もっと知りたいと思ったらChatGPTなどに聞いてみましょう!
最後に
本記事を読んで頂きありがとうございます。
まずは1本目!と思って記事を書いてみましたが、結構ヘビーな感じになってしまいました。
osやdatetimeライブラリはデスクトップアプリを使う際にかなり使えますので、しっかり覚えましょう!