Pythonでフルパスのファイル名を作成する


180

モジュールにファイルパス名を渡す必要があります。ディレクトリ名、ベースファイル名、ファイル形式文字列からファイルパスを作成するにはどうすればよいですか?

ディレクトリは、呼び出し時に存在する場合と存在しない場合があります。

例えば:

dir_name='/home/me/dev/my_reports'
base_filename='daily_report'
format = 'pdf'

文字列を作成する必要があります '/home/me/dev/my_reports/daily_report.pdf'

部分を手動で連結することは良い方法ではないようです。私が試したos.path.join

join(dir_name,base_filename,format)

しかしそれは与える

/home/me/dev/my_reports/daily_report/pdf

回答:


290

これはうまくいきます:

os.path.join(dir_name, base_filename + "." + filename_suffix)

それを念頭に置いて os.path.join()オペレーティングシステムごとに異なるパス区切り文字を使用しているためにのみ存在することに注意し。それはその違いを滑らかにするので、クロスプラットフォームのコードが各OSの特別なケースで雑然としている必要はありません。すべてのOSで、ファイル名の「拡張子」(脚注を参照)は常にドット文字で名前の残りの部分に接続されるため、これを行う必要はありません。

とにかく関数を使用して気分が良くなった場合(そして、コードを不必要に複雑にしたい場合)、次のようにできます。

os.path.join(dir_name, '.'.join((base_filename, filename_suffix)))

コードを簡潔にしたい場合は、接尾辞にドットを含めるだけです。

suffix = '.pdf'
os.path.join(dir_name, base_filename + suffix)

(このアプローチは、Python 3.4で導入されたpathlibのサフィックス規則にも互換性があります。)


脚注:Micorsoft以外のオペレーティングシステムでは、ファイル名の「拡張子」などはありません。Windowsでのその存在は、MS-DOSおよびFATから来ています。MS-DOSおよびFATは、何十年も死んでいるCP / Mからそれを借りました。私たちの多くが慣れているドットプラス3文字は、他のすべての最新のOSのファイル名の一部にすぎず、組み込みの意味はありません。


7
あなたは、OSセパレータがそうでないかもしれないと述べました.。このために使用できますos.extsep
sjbx 2013年

2
私はそのようなことは述べなかった。
ʇsәɹoɈ

6
「ファイル名の「拡張子」は1つの主要なオペレーティングシステムでのみ意味があり(Windows以外のシステムではファイル名の一部にすぎません)、区切り文字は常にドットであることを説明するために、いくつかの長さを説明しました。OPはまた、最後に/ pdfを見たと述べました。だからあなたはできたでしょうos.path.join(dir_name, base_filename, os.extsep, extension)。あなたの答えは完全に正しいです。
sjbx

3
ええ、そうです、それは文字列だけを返すので、os.path.join(dir_name、 '' .join([base_filename、os.extsep、extension]))はそれを行うべきです。繰り返しますが、それはあなたの答えの正確さを損なうものではありません。
sjbx 2013年

1
@sjbxあなたは+ファイル名の部分の間に置くべきです。os.path.join()(OS固有のパスセパレータを追加し/、正しく彼/彼女の答えにそれらを持っているsәɹoɈ@として(引数の間など)このように、あなたのコードスニペットの正しい形式は次のとおりです。os.path.join(dir_name, base_filename + os.extsep + extension)
Shayanアマニ

39

幸運にもPython 3.4以降を実行できる場合は、次を使用できますpathlib

>>> from pathlib import Path
>>> dirname = '/home/reports'
>>> filename = 'daily'
>>> suffix = '.pdf'
>>> Path(dirname, filename).with_suffix(suffix)
PosixPath('/home/reports/daily.pdf')

1
pathlibはos.path.joinよりもはるかにエレガントであることがわかります。
ピオニエール

ファイル名に「。」が含まれている場合は機能しません。>>> filename2 = 'daily.hourly' >>> Path(dirname、filename2).with_suffix(suffix)Output:WindowsPath( '/ home / reports / daily.pdf')
'28年

2
@wontleave:ファイル名にすでにサフィックスが付いている場合はwith_suffix()、追加するのではなく、それを置き換えます。あなたは次のようなものを望みますPath(dirname, filename2 + suffix)
Eugene Yarmash

21

ええと、なぜそれだけではないのですか?

>>>> import os
>>>> os.path.join(dir_name, base_filename + "." + format)
'/home/me/dev/my_reports/daily_report.pdf'

おかげで、しかし、私はその拡張子を追加するよりきれいな方法があることを望んでいました..pythonには、拡張子を切り取るためのsplitext関数さえあります..そのため、逆を行う何かがある必要があります
Damon Julian

2
splitext関数は「。」を保持します。拡張の前部。これはおそらく、最もクリーンな方法です。コード内でより見栄えをよくしたい場合は、関数またはラムダ関数を使用することをお勧めします。
渦度2010

0

os.path.joinパスをファイル名と拡張子で結合するために使用します。sys.argvスクリプトの実行時にスクリプトに渡された引数にアクセスするために使用します。

#!/usr/bin/env python3
# coding: utf-8

# import netCDF4 as nc
import numpy as np
import numpy.ma as ma
import csv as csv

import os.path
import sys

basedir = '/data/reu_data/soil_moisture/'
suffix = 'nc'


def read_fid(filename):
    fid = nc.MFDataset(filename,'r')
    fid.close()
    return fid

def read_var(file, varname):
    fid = nc.Dataset(file, 'r')
    out = fid.variables[varname][:]
    fid.close()
    return out


if __name__ == '__main__':
    if len(sys.argv) < 2:
        print('Please specify a year')

    else:
        filename = os.path.join(basedir, '.'.join((sys.argv[1], suffix)))
        time = read_var(ncf, 'time')
        lat = read_var(ncf, 'lat')
        lon = read_var(ncf, 'lon')
        soil = read_var(ncf, 'soilw')

次のようにスクリプトを実行するだけです。

   # on windows-based systems
   python script.py year

   # on unix-based systems
   ./script.py year
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.