在Python中构建完整路径文件名

问题:在Python中构建完整路径文件名

我需要将文件路径名传递给模块。如何从目录名称,基本文件名和文件格式字符串构建文件路径?

呼叫时目录可能存在也可能不存在。

例如:

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

I need to pass a file path name to a module. How do I build the file path from a directory name, base filename, and a file format string?

The directory may or may not exist at the time of call.

For example:

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

I need to create a string '/home/me/dev/my_reports/daily_report.pdf'

Concatenating the pieces manually doesn’t seem to be a good way. I tried os.path.join:

join(dir_name,base_filename,format)

but it gives

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

回答 0

这工作正常:

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

请记住,这种os.path.join()存在仅是因为不同的操作系统使用不同的路径分隔符。它消除了这种差异,因此跨平台代码不必因每个操作系统的特殊情况而混乱。无需对文件名“扩展名”执行此操作(请参见脚注),因为在每个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,它们是从CP / M借来的,它已经死了几十年。我们中许多人习惯看到的点加三字母只是其他任何现代OS上文件名的一部分,在其中它没有内置的含义。

This works fine:

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

Keep in mind that os.path.join() exists only because different operating systems use different path separator characters. It smooths over that difference so cross-platform code doesn’t have to be cluttered with special cases for each OS. There is no need to do this for file name “extensions” (see footnote) because they are always connected to the rest of the name with a dot character, on every OS.

If using a function anyway makes you feel better (and you like needlessly complicating your code), you can do this:

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

If you prefer to keep your code clean, simply include the dot in the suffix:

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

That approach also happens to be compatible with the suffix conventions in pathlib, which was introduced in python 3.4 after this question was asked. New code that doesn’t require backward compatibility can do this:

suffix = '.pdf'
pathlib.PurePath(dir_name, base_filename + suffix)

You might prefer the shorter Path instead of PurePath if you’re only handling paths for the local OS.

Warning: Do not use pathlib’s with_suffix() for this purpose. That method will corrupt base_filename if it ever contains a dot.


Footnote: Outside of Micorsoft operating systems, there is no such thing as a file name “extension”. Its presence on Windows comes from MS-DOS and FAT, which borrowed it from CP/M, which has been dead for decades. That dot-plus-three-letters that many of us are accustomed to seeing is just part of the file name on every other modern OS, where it has no built-in meaning.


回答 1

如果您有幸能够运行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')

If you are fortunate enough to be running Python 3.4+, you can use pathlib:

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

回答 2

嗯,为什么不只是:

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

Um, why not just:

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

回答 3

只需使用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

Just use os.path.join to join your path with the filename and extension. Use sys.argv to access arguments passed to the script when executing it:

#!/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')

Simply run the script like:

   # on windows-based systems
   python script.py year

   # on unix-based systems
   ./script.py year