Como obter um caminho de arquivo absoluto em Python

Respostas:

1056
>>> import os
>>> os.path.abspath("mydir/myfile.txt")
'C:/example/cwd/mydir/myfile.txt'

Também funciona se já for um caminho absoluto:

>>> import os
>>> os.path.abspath("C:/example/cwd/mydir/myfile.txt")
'C:/example/cwd/mydir/myfile.txt'
Sherbang
fonte
29
Nota: Na maioria das plataformas, isto é equivalente a chamar a função normpath()da seguinte forma: normpath(join(os.getcwd(), path)). Portanto, se mydir/myfile.txtnão o fizer os.getcwd(), o caminho absoluto não será o caminho real .
coanor
32
@coanor? Sem uma raiz explícita, mydir/myfile.txtrefere-se implicitamente a um caminho dentro do diretório de trabalho atual, pois é equivalente a ./mydir/myfile.txt. Esse pode não ser o caminho que você pretendia inserir, mas parece que a interpretação correta do caminho, até onde eu sei. Você poderia elaborar?
Jpmc26
2
@ jpmc26 Eu não sigo exatamente coanor, mas eu diria que (ao contrário do que presumi), não há ligação entre o argumento da abspathfunção e um arquivo real. Você pode fornecer arquivos de nome de caminho inexistentes e as hierarquias de diretório são boas e o abspath simplesmente resolverá os bits do caminho (incluindo o ..elemento " " do diretório pai ) e retornará uma string. Esta é apenas uma string calculada a partir do diretório atual; qualquer correlação com um arquivo real é acidental, ao que parece. Tente os.path.abspath("/wow/junk/../blha/hooey"). Funciona.
Mike S
2
@ MikeS: Eu sinceramente não sei por que isso seria um comportamento inesperado. É um caminho absoluto , não um arquivo ou diretório absoluto. Se você deseja verificar a existência, ligue os.path.exists. Pelo contrário, sistemas como o PowerShell que insistem no caminho existente com a função de resolução de caminho padrão são uma tarefa difícil de usar.
Jpmc26 12/0918
1
@ jpmc26 Assumir que um caminho é apenas uma string que se parece com um nome de caminho não é nada claro e vai contra o modo como venho pensando e falando sobre nomes de caminhos há muitos anos. Cito os documentos do Python 3 para abspath: "Retorne uma versão absolutizada normalizada do caminho do nome do caminho ". Não é uma "... versão do caminho da string ". Um nome de caminho, conforme definido pelo Posix, é "Uma sequência usada para identificar um arquivo". Os documentos do Python são explícitos sobre : "o sistema de arquivos não é acessado para confirmar a existência ou natureza de ". Se o argumento aqui é óbvio, por que ser explícito ? relpathpathrelpath
Mike S
77

Você pode usar a nova biblioteca Python 3.4 pathlib. (Você também pode obtê-lo para Python 2.6 ou 2.7 usando pip install pathlib.) Os autores escreveram : "O objetivo desta biblioteca é fornecer uma hierarquia simples de classes para manipular os caminhos do sistema de arquivos e as operações comuns que os usuários fazem sobre eles".

Para obter um caminho absoluto no Windows:

>>> from pathlib import Path
>>> p = Path("pythonw.exe").resolve()
>>> p
WindowsPath('C:/Python27/pythonw.exe')
>>> str(p)
'C:\\Python27\\pythonw.exe'

Ou no UNIX:

>>> from pathlib import Path
>>> p = Path("python3.4").resolve()
>>> p
PosixPath('/opt/python3/bin/python3.4')
>>> str(p)
'/opt/python3/bin/python3.4'

Os documentos estão aqui: https://docs.python.org/3/library/pathlib.html

twasbrillig
fonte
4
Muito útil. Using os.path.abspath()me deu um erro :, AttributeError: 'NoneType' object has no attribute 'startswith'using Path().resolve()does not com o mesmo caminho de arquivo relativo. (Linux e Python3.4)
NuclearPeon
23

Melhor ainda, instale o módulo (encontrado em PyPI), ele agrupa todas as os.pathfunções e outras funções relacionadas em métodos em um objeto que pode ser usado onde quer que as strings sejam usadas:

>>> from path import path
>>> path('mydir/myfile.txt').abspath()
'C:\\example\\cwd\\mydir\\myfile.txt'
>>>
Tom
fonte
2
Pena que eles nunca conseguiram um módulo de abstração de nome de arquivo adequado no stdlib.
Torsten Marek
1
@Torsten Marek: é uma omissão dolorosa e duradoura.
flow
4
Eles fizeram-se agora para Python 3.4: pathlib. Veja minha resposta neste tópico.
twasbrillig
Existem yypos nesta resposta. Deve ser from path import PathseguidaPath('mydir/myfile.txt').abspath()
frakman1
Não há erros de digitação, você pode estar usando um pathmódulo diferente . O módulo vinculado usa uma classe chamada path.
Tom
10

Atualização para o Python 3.4+ pathlibque realmente responde à pergunta:

from pathlib import Path

relative = Path("mydir/myfile.txt")
absolute = relative.absolute()  # absolute is a Path object

Se você precisar apenas de uma sequência temporária, lembre-se de que pode usar Pathobjetos com todas as funções relevantes os.path, incluindo, é claro abspath:

from os.path import abspath

absolute = abspath(relative)  # absolute is a str object
Físico louco
fonte
9
import os
os.path.abspath(os.path.expanduser(os.path.expandvars(PathNameString)))

Observe que expanduseré necessário (no Unix), caso a expressão fornecida para o nome e o local do arquivo (ou diretório) possa conter um líder ~/(o til refere-se ao diretório inicial do usuário) e expandvarscuida de quaisquer outras variáveis ​​de ambiente (como $HOME).

benjimin
fonte
6

Isso sempre obtém o nome do arquivo correto do script atual, mesmo quando é chamado de outro script. É especialmente útil ao usar subprocess.

import sys,os

filename = sys.argv[0]

a partir daí, você pode obter o caminho completo do script com:

>>> os.path.abspath(filename)
'/foo/bar/script.py'

Também facilita a navegação nas pastas, anexando /..quantas vezes você quiser subir na hierarquia dos diretórios.

Para obter o cwd:

>>> os.path.abspath(filename+"/..")
'/foo/bar'

Para o caminho pai:

>>> os.path.abspath(filename+"/../..")
'/foo'

Ao combinar "/.."com outros nomes de arquivos, você pode acessar qualquer arquivo no sistema.

Lucas Azevedo
fonte
Não era isso que estava sendo perguntado. Eles perguntaram sobre um caminho em relação ao diretório de trabalho atual, que não é a mesma coisa que o diretório de scripts, embora às vezes eles acabem tendo o mesmo valor.
O Elemental da Criação
3

O módulo osfornece uma maneira de encontrar o caminho do abs.

MAS a maioria dos caminhos no Linux começa com~ (til), o que não fornece um resultado satisfatório.

então você pode usar srblibpara isso.

>>> import os
>>> os.path.abspath('~/hello/world')
'/home/srb/Desktop/~/hello/world'
>>> from srblib import abs_path
>>> abs_path('~/hello/world')
'/home/srb/hello/world'

instale-o usando python3 -m pip install srblib

https://pypi.org/project/srblib/

srbcheema1
fonte
1

Eu prefiro usar glob

Aqui está como listar todos os tipos de arquivos na sua pasta atual:

import glob
for x in glob.glob():
    print(x)

Aqui está como listar todos os arquivos .txt (por exemplo) na sua pasta atual:

import glob
for x in glob.glob('*.txt'):
    print(x)

Aqui está como listar todos os tipos de arquivo em um diretório escolhido:

import glob
for x in glob.glob('C:/example/hi/hello/'):
    print(x)

espero que isso tenha ajudado

F. Taylor
fonte
2
Você parece estar respondendo a uma pergunta diferente. Não era "Como obtenho um caminho?", Mas "um caminho absoluto". Pode-se aplicar a resposta correta ( os.path.abspath()) para qualquer caminho relativo globfornece para seus dois primeiros casos ...
NichtJens
1

se você estiver em um mac

import os
upload_folder = os.path.abspath("static/img/users")

isso lhe dará um caminho completo:

print(upload_folder)

mostrará o seguinte caminho:

>>>/Users/myUsername/PycharmProjects/OBS/static/img/user
chikwapuro
fonte
1

Caso alguém esteja usando python e linux e procurando o caminho completo para o arquivo:

>>> path=os.popen("readlink -f file").read()
>>> print path
abs/path/to/file
BND
fonte