【问题标题】:Build the full path filename in Python在 Python 中构建完整路径文件名
【发布时间】:2011-08-20 15:53:08
【问题描述】:

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

调用时目录可能存在也可能不存在。

例如:

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

【问题讨论】:

    标签: python filenames


    【解决方案1】:

    这很好用:

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

    请记住,os.path.join() 的存在只是因为不同的操作系统使用不同的路径分隔符。它消除了这种差异,因此跨平台代码不必因每个操作系统的特殊情况而杂乱无章。对于文件名“扩展名”(见脚注),不需要这样做,因为在每个操作系统上,它们总是用点字符连接到名称的其余部分。

    如果使用函数让您感觉更好(并且您喜欢不必要地使代码复杂化),您可以这样做:

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

    如果您希望保持代码干净,只需在后缀中包含点:

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

    这种方法也恰好与pathlib 中的后缀约定兼容,这是在提出这个问题几年后在 python 3.4 中引入的。不需要向后兼容的新代码可以这样做:

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

    如果您只处理本地操作系统的路径,您可能会想使用较短的 Path() 而不是 PurePath()。考虑到原始问题背后的跨平台问题,我会质疑这种选择。

    警告:不要为此目的使用 pathlib 的 with_suffix()。如果 base_filename 包含点,该方法将损坏它。


    脚注:在 Micorsoft 操作系统之外,没有文件名“扩展名”之类的东西。它在 Windows 上的存在来自 MS-DOS 和 FAT,它从已经死了几十年的 CP/M 借来了它。我们许多人习惯看到的点加三个字母只是其他所有现代操作系统文件名的一部分,它没有内置含义。

    【讨论】:

    • 您提到操作系统分隔符可能不是.。对于这个可以使用os.extsep
    • 我没有提到这件事。
    • 您竭尽全力解释“文件名“扩展名”仅在一种主要操作系统上具有重要意义(它们只是非 Windows 系统上文件名的一部分),以及它们的分隔符始终是一个点'。 OP还表示他们最后看到了/pdf。所以你可以做os.path.join(dir_name, base_filename, os.extsep, extension)。你的答案完全正确。
    • 是的,你是对的,它只返回一个字符串,所以 os.path.join(dir_name, ''.join([base_filename, os.extsep, extension])) 应该这样做。同样,它不会破坏您答案的正确性。
    • @sjbx 你应该把+ 放在文件名部分之间。 os.path.join() 在参数之间添加特定于操作系统的路径分隔符(例如/)(因为@sәɹoɈ 正确地将它们包含在他/她的答案中。因此您的代码 sn-p 的正确形式是:os.path.join(dir_name, base_filename + os.extsep + extension)
    【解决方案2】:

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

    【讨论】:

    • 我发现 pathlib 比 os.path.join 优雅得多,相比之下,os.path.join 看起来相当笨重。
    • 如果您的文件名有“.”则不起作用>>>filename2= 'daily.hourly' >>>Path(dirname, filename2).with_suffix(suffix) 输出:WindowsPath('/home/reports/daily.pdf')
    • @wontleave:如果文件名已经有后缀,with_suffix() 将替换它而不是追加。你想要Path(dirname, filename2 + suffix)
    【解决方案3】:

    嗯,为什么不只是:

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

    【讨论】:

    • 谢谢,但我希望有一种更简洁的方法来附加该扩展名..python 甚至有一个 splitext 函数来切断扩展名..所以必须做一些相反的事情跨度>
    • splitext 函数保留 '.'在扩展的前面。这可能是最干净的方法。如果你想让它在你的代码中“看起来”更干净,我建议使用函数或 lambda 函数。
    【解决方案4】:

    在基本文件名中添加格式不是更好吗?

    dir_name='/home/me/dev/my_reports/'
    base_filename='daily_report.pdf'
    os.path.join(dir_name, base_filename)
    

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:
        from pathlib import Path
        
        # Build paths inside the project like this: BASE_DIR / 'subdir'.
        
        BASE_DIR = Path(__file__).resolve().parent.parent
        TEMPLATE_PATH = Path.joinpath(BASE_DIR,"templates")
        print(TEMPLATE_PATH)
        

        【讨论】:

          猜你喜欢
          • 2018-11-16
          • 1970-01-01
          • 2013-07-17
          • 1970-01-01
          • 2011-01-08
          • 2011-02-02
          • 2014-09-26
          • 1970-01-01
          相关资源
          最近更新 更多