Xây dựng tên tệp đường dẫn đầy đủ trong Python


180

Tôi cần phải chuyển một tên đường dẫn tệp cho một mô-đun. Làm cách nào để tạo đường dẫn tệp từ tên thư mục, tên tệp cơ sở và chuỗi định dạng tệp?

Thư mục có thể tồn tại hoặc không tồn tại tại thời điểm cuộc gọi.

Ví dụ:

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

Tôi cần tạo một chuỗi '/home/me/dev/my_reports/daily_report.pdf'

Ghép các mảnh bằng tay dường như không phải là một cách tốt. Tôi đã thử os.path.join:

join(dir_name,base_filename,format)

nhưng nó cho

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

Câu trả lời:


290

Điều này hoạt động tốt:

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

Hãy nhớ rằng os.path.join()chỉ tồn tại vì các hệ điều hành khác nhau sử dụng các ký tự phân tách đường dẫn khác nhau. Nó làm dịu đi sự khác biệt đó để mã đa nền tảng không phải lộn xộn với các trường hợp đặc biệt cho mỗi HĐH. Không cần thực hiện việc này đối với "phần mở rộng" của tên tệp (xem chú thích) vì chúng luôn được kết nối với phần còn lại của tên bằng ký tự dấu chấm, trên mọi HĐH.

Nếu việc sử dụng một hàm dù sao cũng khiến bạn cảm thấy tốt hơn (và bạn muốn làm phức tạp mã của mình một cách không cần thiết), bạn có thể làm điều này:

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

Nếu bạn muốn giữ mã của mình sạch sẽ, chỉ cần bao gồm dấu chấm trong hậu tố:

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

(Cách tiếp cận này cũng tương thích với các quy ước hậu tố trong pathlib , được giới thiệu trong python 3.4.)


Lưu ý: Không có tên gọi là "phần mở rộng" trên các hệ điều hành không phải là Micorsoft. Sự hiện diện của nó trên Windows đến từ MS-DOS và FAT, vốn đã mượn nó từ CP / M, đã chết trong nhiều thập kỷ. Dấu chấm cộng ba chữ cái mà nhiều người trong chúng ta đã quen nhìn thấy chỉ là một phần của tên tệp trên mọi hệ điều hành hiện đại khác, nơi nó không có nghĩa tích hợp.


7
Bạn đã đề cập rằng trình phân tách hệ điều hành có thể không .. Đối với điều này có thể sử dụng os.extsep.
sjbx 18/03/13

2
Tôi đã đề cập không có điều đó.
ʇsәɹoɈ

6
Bạn đã đi đến một số độ dài để giải thích rằng 'Phần mở rộng "Tên tệp chỉ có ý nghĩa quan trọng trên một hệ điều hành chính (chúng chỉ đơn giản là một phần của tên tệp trên các hệ thống không phải Windows) và ký tự dấu tách của chúng luôn là dấu chấm'. OP cũng bày tỏ họ đã thấy / pdf ở cuối. Vì vậy, bạn có thể đã làm os.path.join(dir_name, base_filename, os.extsep, extension). Câu trả lời của bạn là hoàn toàn chính xác.
sjbx

3
Vâng, bạn đã đúng, nó chỉ trả lại một chuỗi để os.path.join (dir_name, '' .join ([base_filename, os.extsep, phần mở rộng])) nên làm điều đó. Một lần nữa, nó không làm suy yếu tính chính xác của câu trả lời của bạn.
sjbx

1
@sjbx bạn nên đặt +giữa các phần tên tệp. os.path.join()thêm các dấu phân cách đường dẫn dành riêng cho hệ điều hành ( /ví dụ) giữa các đối số (như @ sәɹoɈ có chính xác chúng trong câu trả lời của anh ấy / cô ấy. Do đó, hình thức chính xác của đoạn mã của bạn là:os.path.join(dir_name, base_filename + os.extsep + extension)
Shayan Amani

39

Nếu bạn đủ may mắn để chạy Python 3.4+, bạn có thể sử dụng pathlib:

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

1
Tôi thấy pathlib thanh lịch hơn nhiều so với os.path.join, có vẻ như khá lộn xộn khi so sánh.
pioniere

Không hoạt động nếu tên tệp của bạn có dấu "." >>> filename2 = 'Daily.hourly' >>> Đường dẫn (dirname, filename2) .with_suffix (hậu tố) Kết quả: WindowsPath ('/ home / báo cáo / Daily.pdf')
phát hành

2
@wontleave: Nếu tên tệp đã có hậu tố, with_suffix()sẽ thay thế nó thay vì nối thêm. Bạn muốn một cái gì đó nhưPath(dirname, filename2 + suffix)
Eugene Yarmash

21

Ừm, tại sao không chỉ:

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

cảm ơn, nhưng tôi đã hy vọng có một cách dễ dàng hơn để nối thêm phần mở rộng đó..python thậm chí còn có chức năng splitext để cắt phần mở rộng..có phải có một cái gì đó để làm ngược lại
Damon Julian

2
Hàm splitext giữ lại '.' ở phía trước của phần mở rộng. Đây có thể là cách sạch nhất để làm điều đó. Nếu bạn muốn nó "trông" sạch hơn trong mã của mình, tôi khuyên bạn nên sử dụng hàm hoặc hàm lambda.
Biến động

0

Chỉ cần sử dụng os.path.joinđể tham gia đường dẫn của bạn với tên tệp và phần mở rộng. Sử dụng sys.argvđể truy cập các đối số được truyền vào tập lệnh khi thực thi nó:

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

Đơn giản chỉ cần chạy tập lệnh như:

   # on windows-based systems
   python script.py year

   # on unix-based systems
   ./script.py year
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.