Bangun nama path lengkap dengan Python

180

Saya perlu memberikan nama jalur file ke modul. Bagaimana cara membangun jalur file dari nama direktori, nama file dasar, dan string format file?

Direktori mungkin ada atau tidak ada pada saat panggilan.

Sebagai contoh:

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

Saya perlu membuat string '/home/me/dev/my_reports/daily_report.pdf'

Menggabungkan potongan-potongan secara manual sepertinya bukan cara yang baik. Saya mencoba os.path.join:

join(dir_name,base_filename,format)

tapi itu memberi

/home/me/dev/my_reports/daily_report/pdf
Damon Julian
sumber

Jawaban:

290

Ini berfungsi dengan baik:

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

Perlu diingat bahwa os.path.join()ada hanya karena sistem operasi yang berbeda menggunakan karakter pemisah jalur yang berbeda. Ini menghaluskan perbedaan itu sehingga kode lintas-platform tidak harus berantakan dengan kasus khusus untuk setiap OS. Tidak perlu melakukan ini untuk nama file "ekstensi" (lihat catatan kaki) karena mereka selalu terhubung ke sisa nama dengan karakter titik, di setiap OS.

Jika tetap menggunakan fungsi membuat Anda merasa lebih baik (dan Anda suka menyulitkan kode Anda), Anda dapat melakukan ini:

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

Jika Anda lebih suka menjaga kode Anda tetap bersih, cukup sertakan titik di akhiran:

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

(Pendekatan ini juga kompatibel dengan konvensi sufiks di pathlib , yang diperkenalkan dengan python 3.4.)


Catatan Kaki: Tidak ada nama "ekstensi" nama file pada sistem operasi non-Micorsoft. Kehadirannya di Windows berasal dari MS-DOS dan FAT, yang meminjamnya dari CP / M, yang telah mati selama beberapa dekade. Dot-plus-tiga-huruf yang biasa kita lihat hanyalah bagian dari nama file di setiap OS modern lainnya, yang tidak memiliki makna bawaan.

ʇsәɹoɈ
sumber
7
Anda menyebutkan bahwa pemisah OS mungkin tidak .. Untuk yang satu ini bisa digunakan os.extsep.
sjbx
2
Saya tidak menyebutkan hal seperti itu.
ʇsәɹoɈ
6
Anda berusaha keras untuk menjelaskan bahwa 'Nama file "ekstensi" hanya memiliki arti signifikan pada satu sistem operasi utama (mereka hanya bagian dari nama file pada sistem non-Windows), dan karakter pemisah mereka selalu merupakan titik'. OP juga menyatakan mereka melihat / pdf di akhir. Jadi Anda bisa melakukannya os.path.join(dir_name, base_filename, os.extsep, extension). Jawaban Anda benar sekali.
sjbx
3
Ya, Anda benar, itu hanya mengembalikan string sehingga os.path.join (dir_name, '' .join ([base_filename, os.extsep, extension])) harus melakukannya. Sekali lagi, itu tidak merusak kebenaran jawaban Anda.
sjbx
1
@ sjbx Anda harus meletakkan di +antara bagian nama file. os.path.join()menambahkan pemisah jalur khusus OS ( /misalnya) antara argumen (seperti @ sәɹoɈ sudah benar dalam jawabannya. Dengan demikian bentuk potongan kode Anda yang benar adalah:os.path.join(dir_name, base_filename + os.extsep + extension)
Shayan Amani
39

Jika Anda cukup beruntung menjalankan Python 3.4+, Anda dapat menggunakan pathlib:

>>> from pathlib import Path
>>> dirname = '/home/reports'
>>> filename = 'daily'
>>> suffix = '.pdf'
>>> Path(dirname, filename).with_suffix(suffix)
PosixPath('/home/reports/daily.pdf')
Eugene Yarmash
sumber
1
Saya menemukan pathlib jauh lebih elegan daripada os.path.join, yang tampaknya cukup kikuk jika dibandingkan.
pioniere
Tidak berfungsi jika nama file Anda memiliki "." >>> filename2 = 'daily.hourly' >>> Path (dirname, filename2) .with_suffix (suffix) Output: WindowsPath ('/ home / reports / daily.pdf')
wontleave
2
@wontleave: Jika nama file sudah memiliki akhiran, with_suffix()akan menggantikannya daripada menambahkan. Anda menginginkan sesuatu sepertiPath(dirname, filename2 + suffix)
Eugene Yarmash
21

Um, mengapa tidak adil:

>>>> import os
>>>> os.path.join(dir_name, base_filename + "." + format)
'/home/me/dev/my_reports/daily_report.pdf'
Mark Longair
sumber
terima kasih, tapi saya berharap ada cara yang lebih bersih untuk menambahkan ekstensi itu .. python bahkan memiliki fungsi splitext untuk memotong ekstensi .. jadi harus ada sesuatu untuk dilakukan sebaliknya
Damon Julian
2
Fungsi splitext mempertahankan '.' di bagian depan ekstensi. Ini mungkin cara paling bersih untuk melakukannya. Jika Anda ingin "melihat" pembersih dalam kode Anda, saya sarankan menggunakan fungsi atau fungsi lambda.
Vortisitas
0

Cukup gunakan os.path.joinuntuk bergabung dengan jalur Anda dengan nama file dan ekstensi. Gunakan sys.argvuntuk mengakses argumen yang diteruskan ke skrip saat menjalankannya:

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

Cukup jalankan skrip seperti:

   # on windows-based systems
   python script.py year

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