Por que usar os dois, os.path.abspath e os.path.realpath?
98
Em vários projetos de código aberto, vi pessoas fazerem os.path.abspath(os.path.realpath(__file__))para obter o caminho absoluto para o arquivo atual.
No entanto, acho isso os.path.abspath(__file__)e os.path.realpath(__file__)produzo o mesmo resultado. os.path.abspath(os.path.realpath(__file__))parece ser um pouco redundante.
Existe uma razão para as pessoas estarem usando isso?
os.path.realpath remove links simbólicos nos sistemas operacionais que os suportam.
os.path.abspathsimplesmente remove coisas como .e ..do caminho dando um caminho completo da raiz da árvore de diretórios para o arquivo nomeado (ou link simbólico)
Por exemplo, no Ubuntu
$ ls -l
total 0-rw-rw-r--1 guest guest 0Jun1608:36 a
lrwxrwxrwx 1 guest guest 1Jun1608:36 b -> a
$ python
Python2.7.11(default,Dec152015,16:46:19)[GCC 4.8.4] on linux2
Type"help","copyright","credits"or"license"for more information.>>>from os.path import abspath, realpath
>>> abspath('b')'/home/guest/play/paths/b'>>> realpath('b')'/home/guest/play/paths/a'
Os links simbólicos podem conter caminhos relativos, daí a necessidade de usar ambos. A chamada interna para realpathpode retornar um caminho com ..partes incorporadas , que abspathentão são removidas.
Embora essa resposta descreva a diferença entre as duas funções, não é verdade que o resultado de realpath()pode conter ..componentes e não responde realmente à pergunta de por que você usaria ambos; a resposta de jobrad é mais precisa.
Miles
Para Python 3.7 e Windows, o realpath não entende as unidades subestadas. Portanto, para uma unidade subestada, diga P: \, tendo a pasta de origem c: \ MyFolder \ Bla, realpath retorna P: \ não c: \ MyFolder \ Bla. Alguém sabe como pegar o caminho "real"?
Totte Karlsson
Para mim, abspathainda segue os links simbólicos se o diretório atual for um link simbólico. Eu só encontrei esta resposta stackoverflow.com/questions/54665065/… para interromper esse comportamento.
Victor Sergienko
107
Para o seu cenário declarado, não há razão para combinar realpath e abspath, uma vez que os.path.realpathrealmente chama os.path.abspathantes de retornar um resultado (eu verifiquei Python 2.5 para Python 3.6).
os.path.abspath retorna o caminho absoluto, mas NÃO resolve links simbólicos em seu argumento.
os.path.realpath primeiro resolverá quaisquer links simbólicos no caminho e, em seguida, retornará o caminho absoluto.
No entanto, se você espera que seu caminho contenha um ~, nem abspath nem realpath serão resolvidos ~para o diretório inicial do usuário e o caminho resultante será inválido . Você precisará usar os.path.expanduserpara resolver isso no diretório do usuário.
Para uma explicação completa, aqui estão alguns resultados que verifiquei no Windows e no Linux, no Python 3.4 e no Python 2.6. O diretório atual ( ./) é meu diretório inicial, que se parece com isto:
myhome
|- data (symlink to /mnt/data)|- subdir (extra directory,for verbose explanation)
# os.path.abspath returns the absolute path, but does NOT resolve symlinks in its argument
os.path.abspath('./')'/home/myhome'
os.path.abspath('./subdir/../data')'/home/myhome/data'# os.path.realpath will resolve symlinks AND return an absolute path from a relative path
os.path.realpath('./')'/home/myhome'
os.path.realpath('./subdir/../')'/home/myhome'
os.path.realpath('./subdir/../data')'/mnt/data'# NEITHER abspath or realpath will resolve or remove ~.
os.path.abspath('~/data')'/home/myhome/~/data'
os.path.realpath('~/data')'/home/myhome/~/data'# And the returned path will be invalid
os.path.exists(os.path.abspath('~/data'))False
os.path.exists(os.path.realpath('~/data'))False# Use realpath + expanduser to resolve ~
os.path.realpath(os.path.expanduser('~/subdir/../data'))'/mnt/data'
Agradável. Para enfatizar, seu último exemplo deveria seros.path.realpath(os.path.expanduser('~/subdir/../data'))
Arthur,
3
Então também não se esqueça de os.path.expandvars se as variáveis forem usadas em um caminho
Slavenskij
7
Em termos gerais, se você está tentando obter o caminho de um arquivo de atalho, caminho absoluto fornece o caminho completo do arquivo presente no local do atalho , enquanto realpath fornece o caminho do local original do arquivo.
Caminho absoluto, os.path.abspath (), fornece o caminho completo do arquivo que está localizado no diretório de trabalho atual ou no diretório que você mencionou.
Caminho real, os.path.realpath (), fornece o caminho completo do arquivo que está sendo referido.
realpath()
pode conter..
componentes e não responde realmente à pergunta de por que você usaria ambos; a resposta de jobrad é mais precisa.abspath
ainda segue os links simbólicos se o diretório atual for um link simbólico. Eu só encontrei esta resposta stackoverflow.com/questions/54665065/… para interromper esse comportamento.Para o seu cenário declarado, não há razão para combinar realpath e abspath, uma vez que
os.path.realpath
realmente chamaos.path.abspath
antes de retornar um resultado (eu verifiquei Python 2.5 para Python 3.6).os.path.abspath
retorna o caminho absoluto, mas NÃO resolve links simbólicos em seu argumento.os.path.realpath
primeiro resolverá quaisquer links simbólicos no caminho e, em seguida, retornará o caminho absoluto.No entanto, se você espera que seu caminho contenha um
~
, nem abspath nem realpath serão resolvidos~
para o diretório inicial do usuário e o caminho resultante será inválido . Você precisará usaros.path.expanduser
para resolver isso no diretório do usuário.Para uma explicação completa, aqui estão alguns resultados que verifiquei no Windows e no Linux, no Python 3.4 e no Python 2.6. O diretório atual (
./
) é meu diretório inicial, que se parece com isto:fonte
os.path.realpath(os.path.expanduser('~/subdir/../data'))
Em termos gerais, se você está tentando obter o caminho de um arquivo de atalho, caminho absoluto fornece o caminho completo do arquivo presente no local do atalho , enquanto realpath fornece o caminho do local original do arquivo.
Caminho absoluto, os.path.abspath (), fornece o caminho completo do arquivo que está localizado no diretório de trabalho atual ou no diretório que você mencionou.
Caminho real, os.path.realpath (), fornece o caminho completo do arquivo que está sendo referido.
Por exemplo:
fonte