สร้างชื่อไฟล์พา ธ เต็มใน Python


181

ฉันต้องส่งชื่อไฟล์พา ธ ไปยังโมดูล ฉันจะสร้างพา ธ ไฟล์จากชื่อไดเรกทอรีชื่อไฟล์พื้นฐานและสตริงรูปแบบไฟล์ได้อย่างไร

ไดเรกทอรีอาจหรือไม่อาจมีอยู่ในช่วงเวลาของการโทร

ตัวอย่างเช่น:

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.path.join(dir_name, '.'.join((base_filename, filename_suffix)))

หากคุณต้องการรักษาความสะอาดโค้ดของคุณเพียงแค่ใส่จุดในคำต่อท้าย:

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

(วิธีนี้ยังเกิดขึ้นเพื่อให้เข้ากันได้กับอนุสัญญาต่อท้ายในpathlibซึ่งได้รับการแนะนำใน python 3.4)


เชิงอรรถ: ไม่มีสิ่งเช่นชื่อไฟล์ "นามสกุล" บนระบบปฏิบัติการที่ไม่ใช่ Micorsoft การปรากฏตัวบน Windows มาจาก MS-DOS และ FAT ซึ่งยืมมาจาก CP / M ซึ่งตายมานานหลายทศวรรษ จุดบวกสามตัวอักษรที่พวกเราหลายคนคุ้นเคยกับการมองเห็นเป็นเพียงส่วนหนึ่งของชื่อไฟล์ในระบบปฏิบัติการสมัยใหม่อื่น ๆ ที่ไม่มีความหมายในตัว


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әɹoɈให้ถูกต้องในคำตอบของเขา / เธอดังนั้นรูปแบบที่ถูกต้องของข้อมูลโค้ดของคุณคือ:os.path.join(dir_name, base_filename + os.extsep + extension)
Shayan Amani

41

หากคุณโชคดีพอที่จะใช้งาน 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')

2
ฉันพบว่า pathlib นั้นมีความสวยงามมากกว่า os.path.join ซึ่งดูเหมือนว่าจะค่อนข้างน่าเบื่อเมื่อเปรียบเทียบ
pioniere

ไม่ทำงานหากชื่อไฟล์ของคุณมี "" >>> filename2 = 'daily.hourly' >>> พา ธ (dirname, filename2) .with_suffix (คำต่อท้าย) เอาท์พุท: WindowsPath ('/ home / reports / daily.pdf')
เสียค่าใช้จ่าย

2
@wontleave: หากชื่อไฟล์มีคำต่อท้ายอยู่แล้วwith_suffix()จะเป็นการแทนที่ด้วยการต่อท้าย คุณต้องการอะไรเช่นPath(dirname, filename2 + suffix)
Eugene Yarmash

22

อืมทำไมไม่เพียงแค่:

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

ขอบคุณ แต่ฉันหวังว่าจะมีวิธีการต่อท้ายที่สะอาดยิ่งขึ้น .. ไพ ธ อนยังมีฟังก์ชั่น splitext เพื่อตัดส่วนขยายออก ... ดังนั้นจะต้องมีสิ่งที่ต้องทำย้อนกลับ
Damon Julian

2
ฟังก์ชั่น splitext รักษา '.' ที่ด้านหน้าของส่วนขยาย นี่น่าจะเป็นวิธีที่สะอาดที่สุด หากคุณต้องการให้มัน "สะอาด" ในโค้ดของคุณฉันขอแนะนำให้ใช้ฟังก์ชั่นหรือฟังก์ชั่นแลมบ์ดา
Vorticity

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.