今回は、Pythonでパスを指定する際に知っていると便利な知識について解説します。
皆さんも、パスの階層移動時に「\」が消えて移動できなかったり、変数を指定する際にパスが煩雑になったりした経験があるのではないでしょうか。
また、拡張子を消した状態のファイル名が取得したいとか、フォルダ名のみ取得したい、など特定の部分のパスのみを取得したいこともあると思います。
今回の内容を覚えれば、フォルダやファイルなど指定で苦労することはなくなると思います。
また、今回紹介する内容は組み合わせることでさらに効果を発揮するので、ぜひ全てマスターしてみてください!
パス関係についてマスターし、Pythonをより便利に使っていきましょう!
階層移動の書き方(Windows)
階層移動が失敗する理由
皆さんは、指定のファイルまでのパスを記入した後、ファイルを開いてみると開けなかった経験はないでしょうか?
例えば、下のようなケースですね。
・inputファイルの中のテキストデータを開きたい。
open(“input\test.txt”)
※この形式ではエラーになります。
このように書くと、Pythonではファイルを開くことが出来ません。
その理由は、バックスラッシュ「\」がPythonでは「エスケープ文字」として認識されてしまうためです。
エスケープ文字って何?と思った方もいらっしゃると思いますが、簡単に説明すると、特殊な機能がある文字を普通の文字として扱えるようにするものです。
ただし大事なのはそこではなく、「\」がそのままでは階層移動に使えないところです。
ではどうすればよいのかというと、下のようにバックスラッシュ「\」を二つ重ねます!
open(“input\\test.txt”)
※「\\」とする必要がある
このようにすれば階層を移動することが出来ますが、WindowsPCでは「\」一つで移動しているので、パスのコピー&ペーストですぐに指定できない、という問題が生じてしまいます。
(あと、単純に毎回「\」を2つ記述するのもめんどくさいですし、コードも煩雑になりますよね。)
そこで、次に紹介する方法をお勧めします!
階層移動の便利な書き方(raw文字の使用)
バックスラッシュ「\」一つで階層を移動するためには、「raw文字」と呼ばれるものを使用します。
raw文字を使う準備は、パスの前に「r」を付けるだけで完了です。
具体的には、下のように書きます。
open(r“input\test.txt”)
※文字指定の「”」の前に書くこと
このようにするだけで、「\」一つで階層移動できるようになりますので、ぜひ覚えておいてください!
フォルダやファイルの指定には「\」は必ずと言ってよいほど使用するので、思った以上に便利です。
ちなみに、下のように両者を比較すると、まったく同じものといった結果が返ってきます。
path1 = "input\\test.txt"
path2 = r"input\test.txt"
print(path1 == path2)
#True
では、階層移動についてまとめておきます。
階層移動に関しては、下のことを覚えておけば大丈夫です。
- Pythonでは、バックスラッシュ「\」一つでは階層を移動できない。
- 階層移動の方法は、「\」を二つ重ねるか、raw文字を使用する。
- 文字指定「”」の前に「r」を付けるだけのraw文字の書き方がおすすめ!
変数の書き方(format文)
パスの中に変数を入れる方法(基本編)
Pythonでパスを指定する場合、変数の名前をパス名に指定したくなる場合が多々あると思います。
例えば以下のようなケースですね。
- ループ処理をして順番に結果を出力する場合に、ループの番号をパスに含めたい。
- 共通のパス名が長い場合、先に変数に入れておいて呼び出したい。
変数を用いる場合は、文字指定「”」の外に出す必要があるため、以下のように書きます。
変数+”文字”+変数+”文字”
※変数と文字は「+」で繋ぐ
文字だけだとイメージしにくいと思うので、実際にコードを見てみましょう。
import os
for day in range(1,10):
for hour in range(24):
filename = "output\\"+str(day)+"日"+str(hour)+"時"
os.makedirs(filename, exist_ok=True)
上のように、毎回文字を「”」でくくり、変数との間を「+」で繋ぐ必要があり、かなり煩雑で読みづらくなります。
また、前述したraw文字も使いづらくなるため、この書き方はお勧めしません。
次項で説明する、「format」を使った書き方をぜひマスターしてください!
ちなみに、上のコードを実行数すると、「output」というフォルダの中に下のようなフォルダが出来上がります。
format文字列を使ってパスの中に変数を入れる方法(おすすめ)
ではお勧めの記述方法である「format文字列」を使った記述方法について解説します。
format文字列を使うには、文字指定「”」の前に「f」を記述して変数を「{}」で囲うだけです!
f“{変数}文字{変数}文字”
※先頭の「f」と変数を文字で囲うだけ
前述の「+」で繋ぐ方法より遥かに分かりやすくなりますね。
先ほどのフォルダ指定方法と比べると一目瞭然です!
また、「raw文字」と同時に使用することができるので、下のように書けます。
※(「f」と「r」はどちらが先でも問題ありません。)
#「+」を使って繋いだパス指定
filename = "output\\"+str(day)+"日"+str(hour)+"時"
#「format文字列」を使って繋いだパス指定
filename = fr"output\{day}日{hour}時"
format文字列を使うことで、数字を文字に変換する必要もなくなり、かなりスッキリしていますね!
また、format文字のように形式を指定することも可能です。
例えば、下のようにゼロ埋めした文字列にしたりできます。
import os
for day in range(1,10):
for hour in range(24):
filename = fr"output\{day:0>2d}日{hour:0>2d}時"
os.makedirs(filename, exist_ok=True)
format文の書き方にについて詳しく知りたい方は、下の記事で解説していますので、良ければそちらもご覧ください。
では、変数の書き方についてまとめておきます。
変数の書き方については以下のことを覚えておけば大丈夫です。
- 変数と文字を組み合わせるには、「+」で間をつなぐ方法と「format文字列」を使う方法がある
- 文字列の先頭に「f」を記載し、変数を「{}」で囲う「format文字列」がおすすめ!
- 「raw文字」とも併用可能
特定の名前のファイル・フォルダ抽出(glob+ワイルドカード「*」)
フォルダやファイル名の一部分を指定したり、特定の拡張子を指定したりしてフォルダやファイルのパスを取得したいことがありますよね。
そんな時は、「glob」とワイルドカード「*」を使うことで簡単にパスを取得することが出来ます!
使い方は下のように使います。(例を挙げて説明します)
・パスの一部分のみ指定したい(例:「test」を含むファイルの取得)
glob(“*test*”)
・特定の拡張子のファイルを取得(例:csvファイルを取得)
glob(“*.csv”)
このように、指定したい文字列とその他なんでも入ってよい箇所にワイルドカード「*」を記載することで、ファイルやフォルダのパスをを取得することが出来ます。
では、実際にコードを動かして確認してみましょう。
下のように、いろいろな名前や拡張子のファイルを用意して、ファイル名を抽出してみます。
from glob import glob
filename1 = glob("*.txt")
filename2 = glob("*test*")
print(filename1)
print(filename2)
# ['test.txt', 'work.txt']
# ['test.txt', 'test2.dat']
filename1で拡張子が「txt」のファイル名を抽出し、filename2ではファイル名に「test」が入っているものを抽出しました。
このように、「glob」とワイルドカード「*」を使うことで自由にファイル名をやパスを取得することが出来ます!
ファイル名やパスの取得に関しては、下記の記事で詳しくまとめていますので、気になる方はそちらもご覧ください。
ファイル・フォルダ名の抽出について以下の内容を覚えておきましょう!
部分的なパスの切り取り(split)
最後に、抽出したパスを部分的に切り取る方法について解説します。
パスに限らず、Pythonでは文字の切り取りに「split」を使います。
「split」は以下のように使用します。
文字列.split(“区切り文字”)
※区切られた文字はlist形式で返される。
このように、「split」+「区切り文字」を指定することで、区切り文字で区切られた文字列がlistとして取得できます。
ただし、階層で区切るために区切り文字にバックスラッシュ「\」を使用する場合は、「\\」のように2つ重ねてください!
※前述したエスケープ文字の関係です。この時はraw文字が使えません。
では実際に、以下の3ケースのパス区切りについてコードを見ながら確認してみましょう。
- パスのファイル名のみ取得
- パスのフォルダ名のみ取得
- 拡張子を除いたファイル名の取得
from glob import glob
filename = fr"input\test.txt"
# 1.ファイル名のみ取得
filename1 = filename.split("\\")[-1]
# 2.フォルダ名のみ取得
filename2 = filename.split("\\")[0]
# 3. 拡張子を除いたファイル名取得
filename3 = filename.split("\\")[-1].split(".")[0]
print(filename1)
print(filename2)
print(filename3)
# test.txt
# input
# test
それぞれ、思い通りにファイル名・フォルダ名を取得することが出来ました。
ちなみに、list形式で出力されますが、list形式って何?と思った方は下の記事の「Pythonで複数の変数を使ってみよう(list)」で解説していますので、そちらをご覧ください。
では、パスの区切りについてまとめておきます。
- 「split」+「区切り文字」の指定でパスを自在に切り取ることが出来る
- ただし、階層で区切るためバックスラッシュ「\」を使用する場合は「\\」のように2つ重ねる!
- 切り取ったパスは、区切られた状態で「list形式」で出力される
まとめ
今回は、Pythonでパスを指定する際に知っていると便利な知識について解説しました。
全体をまとめると以下のような内容でしたね。
- 文字指定「”」の前に「r」を付けるraw文字で階層移動の記載を簡略化できる
- 文字指定「”」の前に「f」を付けるformat文字列で文字列+変数の記載を簡略化できる
- 「glob」とワイルドカード「*」を使うことで簡単にパスを取得することが出来る
- 「split」+「区切り文字」の指定でパスを自在に切り取ることが出来る
これらは、単体でも十分効果的ですが、組み合わせることでパス関連の処理が驚くほど楽になります!
皆さんもぜひ今回の内容をマスターしてみてください。
また、このサイトでは初心者の方向けに「プログラミングのお勧め学習法」も紹介していますので、気になった方はそちらもご覧いただけると幸いです。
コメント