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


179

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

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

例如:

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

Answers:


288

这工作正常:

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上文件名的一部分,在其中它没有内置的含义。


7
您提到操作系统分隔符可能不是.。为此,可以使用os.extsep
sjbx

2
我没有提到这样的事情。
ʇsәɹoɈ

6
您花了一些时间来解释“文件名“扩展名”仅在一个主要操作系统上才具有重要意义(在非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

1
@sjbx应该放在+文件名部分之间。在参数之间os.path.join()添加特定/于OS的路径分隔符(例如@sәɹoanswer正确地将其包含在他/她的答案中。因此,代码段的正确形式是:os.path.join(dir_name, base_filename + os.extsep + extension)
Shayan Amani

38

如果您有幸能够运行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更优雅,相比之下os.path.join显得笨拙。
pioniere'5

如果文件名带有“。”则不起作用 >>> filename2 ='daily.hourly'>>> Path(dirname,filename2).with_suffix(suffix)Output:WindowsPath('/ home / reports / daily.pdf')
willtleave

1
@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函数来切断扩展名。.so必须采取一些相反的措施
Damon Julian

2
splitext函数保留“。”。在扩展名的前面。这可能是最干净的方法。如果您希望它在代码中“看起来”更整洁,建议您使用一个函数或一个lambda函数。
漩涡

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.