¿Por qué uno usaría ambos, os.path.abspath y os.path.realpath?

En varios proyectos de código abierto, he visto a personas hacer os.path.abspath(os.path.realpath(__file__)) para obtener la ruta absoluta al archivo actual.

Sin embargo, encuentro que os.path.abspath(__file__) y os.path.realpath(__file__) producen el mismo resultado. os.path.abspath(os.path.realpath(__file__)) parece ser un poco redundante.

¿Hay alguna razón por la que la gente está usando eso?

os.path.realpath elimina enlaces simbólicos en aquellos sistemas operativos que los admiten.

os.path.abspath simplemente elimina cosas como . y .. desde la ruta que proporciona una ruta completa desde la raíz del árbol de directorios al archivo nombrado (o enlace simbólico)

Por ejemplo, en Ubuntu

 $ ls -l total 0 -rw-rw-r-- 1 guest guest 0 Jun 16 08:36 a lrwxrwxrwx 1 guest guest 1 Jun 16 08:36 b -> a $ python Python 2.7.11 (default, Dec 15 2015, 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' 

Los enlaces simbólicos pueden contener rutas relativas, de ahí la necesidad de usar ambas. La llamada interna a realpath puede devolver una ruta con partes integradas .. , que luego se elimina abspath .

Para el escenario indicado, no hay ninguna razón para combinar realpath y abspath, ya que os.path.realpath realidad llama a os.path.abspath antes de devolver un resultado (verifiqué Python 2.5 en Python 3.6).

  • os.path.abspath devuelve la ruta absoluta, pero NO resuelve los enlaces simbólicos.
  • os.path.realpath primero resolverá cualquier enlace simbólico en la ruta y luego devolverá la ruta absoluta.

Sin embargo, si espera que su ruta contenga un ~ , ni abspath ni realpath se resolverán ~ en el directorio de inicio del usuario, y la ruta resultante no será válida . Deberá usar os.path.expanduser para resolver esto en el directorio del usuario.

Para una explicación detallada, aquí hay algunos resultados que he verificado en Windows y Linux, en Python 3.4 y Python 2.6. El directorio actual ( ./ ) es mi directorio principal, que se parece a esto:

 myhome |- data (symlink to /mnt/data) |- subdir (extra directory, for verbose explanation) 
 # os.path.abspath returns the absolute path, but does NOT resolve symlinks 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' 

En términos simples, si está intentando obtener la ruta de acceso de un archivo de acceso directo, la ruta de acceso absoluta proporciona la ruta completa del archivo presente en la ubicación del acceso directo , mientras que realpath proporciona la ruta de ubicación original del archivo.

La ruta absoluta, os.path.abspath (), proporciona la ruta completa del archivo que se encuentra en el directorio de trabajo actual o en el directorio que mencionó.

La ruta real, os.path.realpath (), proporciona la ruta completa del archivo al que se hace referencia.

P.ej:

 file = "shortcut_folder/filename" os.path.abspath(file) = "C:/Desktop/shortcut_folder/filename" os.path.realpath(file) = "D:/PyCharmProjects/Python1stClass/filename"