Crie o nome do arquivo do caminho completo em Python


180

Eu preciso passar um nome de caminho de arquivo para um módulo. Como crio o caminho do arquivo a partir de um nome de diretório, nome de arquivo base e uma string de formato de arquivo?

O diretório pode ou não existir no momento da chamada.

Por exemplo:

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

Eu preciso criar uma string '/home/me/dev/my_reports/daily_report.pdf'

Concatenar as peças manualmente não parece ser uma boa maneira. Eu tentei os.path.join:

join(dir_name,base_filename,format)

mas dá

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

Respostas:


290

Isso funciona bem:

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

Lembre-se de que os.path.join()existe apenas porque sistemas operacionais diferentes usam caracteres separadores de caminho diferentes. Ele suaviza essa diferença, para que o código de plataforma cruzada não precise ser confundido com casos especiais para cada sistema operacional. Não é necessário fazer isso para as "extensões" do nome do arquivo (consulte a nota de rodapé), pois elas sempre estão conectadas ao restante do nome com um caractere de ponto, em todos os sistemas operacionais.

Se usar uma função de qualquer maneira faz você se sentir melhor (e você gosta de complicar desnecessariamente o seu código), você pode fazer o seguinte:

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

Se você preferir manter seu código limpo, basta incluir o ponto no sufixo:

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

(Essa abordagem também é compatível com as convenções de sufixo no pathlib , que foram introduzidas no python 3.4.)


Nota de rodapé: Não existe uma "extensão" de nome de arquivo em sistemas operacionais que não sejam da Micorsoft. Sua presença no Windows vem do MS-DOS e FAT, que o emprestaram do CP / M, que está morto há décadas. Esse ponto com mais três letras que muitos de nós estamos acostumados a ver é apenas parte do nome do arquivo em qualquer outro sistema operacional moderno, onde ele não tem significado embutido.


7
Você mencionou que o separador do SO pode não ser .. Para isso, pode-se usar os.extsep.
sjbx

2
Eu não mencionei isso.
ʇsәɹoɈ

6
Você se esforçou ao máximo para explicar que 'extensões de nome de arquivo' têm apenas um significado significativo em um sistema operacional principal (elas são simplesmente parte do nome de arquivo em sistemas não Windows), e o caractere separador é sempre um ponto '. O OP também expressou que viu / pdf no final. Então você poderia ter feito os.path.join(dir_name, base_filename, os.extsep, extension). Sua resposta está perfeitamente correta.
sjbx

3
Sim, você está certo, ele devolve apenas uma string para que os.path.join (dir_name, '' .join ([base_filename, os.extsep, extension])) faça isso. Novamente, isso não prejudica a exatidão de sua resposta.
Sjbx

1
@sjbx você deve colocar +entre as partes do nome do arquivo. os.path.join()Adiciona OS-específicas separadores de caminho ( /por exemplo) entre os argumentos (como @ sәɹoɈ corretamente tê-los em seu / sua resposta Assim, a forma correta de seu trecho de código é:.os.path.join(dir_name, base_filename + os.extsep + extension)
Shayan Amani

39

Se você tiver a sorte de executar o Python 3.4+, poderá usar pathlib:

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

1
Acho pathlib muito mais elegante que os.path.join, o que parece bastante desajeitado em comparação.
Pioniere 6/05/19

Não funciona se o nome do arquivo tiver um "." >>> filename2 = 'daily.hourly' >>> Caminho (dirname, filename2) .with_suffix (sufixo) Saída: WindowsPath ('/ home / reports / daily.pdf')
wontleave

2
@ wontleave: Se um nome de arquivo já tiver um sufixo, ele with_suffix()será substituído em vez de anexado. Você quer algo comoPath(dirname, filename2 + suffix)
Eugene Yarmash

21

Hum, por que não apenas:

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

Obrigado, mas eu estava esperando que houvesse uma maneira mais limpa de acrescentar que extension..python ainda tem uma função splitext para cortar a extension..so tem que haver algo para fazer o inverso
Damon Julian

2
A função splitext mantém o '.' na frente da extensão. Esta é provavelmente a maneira mais limpa de fazer isso. Se você quiser "parecer" mais limpo em seu código, sugiro usar uma função ou uma função lambda.
Vorticity

0

Basta usar os.path.joinpara ingressar no seu caminho com o nome do arquivo e a extensão. Use sys.argvpara acessar os argumentos passados ​​para o script ao executá-lo:

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

Basta executar o script como:

   # on windows-based systems
   python script.py year

   # on unix-based systems
   ./script.py year
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.