Python'da tam yol dosya adını oluşturma


181

Modüle bir dosya yolu adı iletmem gerekiyor. Dosya yolunu dizin adı, temel dosya adı ve dosya biçimi dizesinden nasıl oluştururum?

Dizin, çağrı sırasında mevcut olabilir veya olmayabilir.

Örneğin:

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

Bir dize oluşturmam gerekiyor '/home/me/dev/my_reports/daily_report.pdf'

Parçaları manuel olarak birleştirmek iyi bir yol gibi görünmüyor. Denedim os.path.join:

join(dir_name,base_filename,format)

ama verir

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

Yanıtlar:


290

Bu iyi çalışıyor:

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

os.path.join()Yalnızca farklı işletim sistemleri farklı yol ayırıcı karakterler kullandığından var olduğunu unutmayın . Bu farklılığı düzeltir, böylece platformlar arası kodun her işletim sistemi için özel durumlarla karıştırılması gerekmez. Dosya adı "uzantıları" için bunu yapmaya gerek yoktur (bkz. Dipnot), her işletim sisteminde her zaman nokta karakteriyle adın geri kalanına bağlanırlar.

Yine de bir işlev kullanmak sizi daha iyi hissettiriyorsa (ve kodunuzu gereksiz yere karmaşıklaştırmayı seviyorsanız), bunu yapabilirsiniz:

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

Kodunuzu temiz tutmayı tercih ederseniz, noktanın sonekini eklemeniz yeterlidir:

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

(Bu yaklaşım , python 3.4'te tanıtılan pathlib'deki sonek kurallarıyla da uyumludur .)


Dipnot: Micorsoft olmayan işletim sistemlerinde dosya adı "uzantısı" diye bir şey yoktur. Windows'daki varlığı, MS-DOS ve FAT tarafından on yıllardır ölü olan CP / M'den ödünç alınmıştır. Birçoğumuzun görmeye alışık olduğu nokta artı üç harf, yerleşik bir anlamı olmayan diğer tüm modern işletim sistemlerindeki dosya adının sadece bir parçasıdır.


7
İşletim sistemi ayırıcısının olmayabilir .. Bunun için kullanabilirsiniz os.extsep.
sjbx

2
Böyle bir şeyden bahsetmedim.
ɈsәɹoɈ

6
'Dosya adı "uzantılarının" yalnızca bir büyük işletim sisteminde önemli bir anlamı olduğunu (Windows olmayan sistemlerde dosya adının bir parçası olduklarını) ve ayırıcı karakterlerinin her zaman bir nokta olduğunu açıklamak için bazı uzunluklara gittiniz. OP ayrıca sonunda / pdf gördüklerini ifade etti. Yani yapabilirdin os.path.join(dir_name, base_filename, os.extsep, extension). Cevabınız tamamen doğru.
sjbx

3
Evet, haklısın, sadece bir dize veriyor, bu yüzden os.path.join (dir_name, '' .join ([base_filename, os.extsep, extension])) yapmalı. Yine, cevabınızın doğruluğunu zayıflatmaz.
sjbx

1
@sjbx +dosya adı bölümleri arasına koymalısınız . argümanlar arasına os.path.join()işletim sistemine özgü yol ayırıcılar ( /örneğin) ekler (@ sәɹoɈ doğru cevap verdiğinde) Kod pasajınızın doğru şekli:os.path.join(dir_name, base_filename + os.extsep + extension)
Shayan Amani

41

Python 3.4+ çalıştıracak kadar şanslıysanız, aşağıdakileri kullanabilirsiniz 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'i os.path.join'den çok daha zarif buluyorum, bu karşılaştırma ile oldukça tıknaz görünüyor.
pioniere

Dosya adınız "" ise çalışmaz. >>> dosyaadı2 = 'daily.hourly' >>> Yol (dizin adı, dosyaadı2) .with_suffix (sonek) Çıktı: WindowsPath ('/ home / raporlar / daily.pdf')
19'da

2
@wontleave: Bir dosya adında zaten bir sonek varsa, with_suffix()eklemek yerine bu dosyanın yerine geçer. Sen gibi bir şey istiyorsunPath(dirname, filename2 + suffix)
Eugene Yarmash

22

Um, neden sadece:

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

teşekkürler, ama ben bu uzantı ekleme daha temiz bir yolu olduğunu umuyordum ... python bile uzatma kesmek için bir splitext işlevi vardır ... yani ters yapmak için bir şey olmalı
Damon Julian

2
Splitext işlevi '.' Değerini korur. uzantısının önünde. Muhtemelen bunu yapmanın en temiz yolu. Kodunuzda "daha temiz" görünmesini istiyorsanız, bir işlev veya lambda işlevi kullanmanızı öneririm.
Vorticity

0

os.path.joinDosya adınız ve uzantıyla yolunuzu birleştirmek için kullanın . kullanımsys.argvKomut dosyasını yürütürken iletilen bağımsız değişkenlere erişmek için :

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

Sadece betiği aşağıdaki gibi çalıştırın:

   # on windows-based systems
   python script.py year

   # on unix-based systems
   ./script.py year
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.