Obtener la ubicación (ruta) de un archivo en ejecución en Python: __file__.

Negocio

Para obtener la ubicación (ruta) de un archivo de script en ejecución en Python, utilice __file__. Esto es útil para cargar otros archivos basándose en la ubicación del archivo en ejecución.

Hasta Python 3.8, __file__ devuelve la ruta especificada al ejecutar el comando python (o el comando python3 en algunos entornos). Si se especifica una ruta relativa, se devuelve la ruta relativa; si se especifica una ruta absoluta, se devuelve la ruta absoluta.

En Python 3.9 y posteriores, se devuelve la ruta absoluta independientemente de la ruta especificada en tiempo de ejecución.

Se explican los siguientes contenidos.

  • os.getcwd(),__file__
  • Obtiene el nombre del archivo y el nombre del directorio del archivo que se está ejecutando actualmente.
  • Obtiene la ruta absoluta del archivo que se está ejecutando.
  • Lee otros archivos en función de la ubicación del archivo que se está ejecutando.
  • Mueve el directorio actual al directorio del archivo que se está ejecutando.
  • Se puede realizar el mismo procesamiento independientemente del directorio actual en tiempo de ejecución.

Consulte el siguiente artículo para obtener información sobre cómo obtener y cambiar el directorio actual (directorio de trabajo).

Tenga en cuenta que __file__ no puede utilizarse en Jupyter Notebook (.ipynb).
El directorio donde se encuentra .ipynb se ejecutará como directorio actual, independientemente del directorio donde se inicie Jupyter Notebook.
Es posible utilizar os.chdir() en el código para cambiar el directorio actual.

os.getcwd() y __file__.

En Windows, puede utilizar el comando dir en lugar de pwd para comprobar el directorio actual.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

Cree un archivo de script Python (file_path.py) con el siguiente contenido en el nivel inferior (data\src).

import os

print('getcwd:      ', os.getcwd())
print('__file__:    ', __file__)

Ejecute el comando python (o el comando python3 en algunos entornos) especificando la ruta del archivo de script.

python3 data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     data/src/file_path.py

La ruta absoluta del directorio actual se puede obtener con os.getcwd(). También se puede utilizar __file__ para obtener la ruta especificada por el comando python3.

Hasta Python 3.8, __file__ contendrá la ruta especificada en el comando python (o python3). En el ejemplo anterior, se devuelve la ruta relativa porque es relativa, pero se devuelve la ruta absoluta si es absoluta.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py

Python 3.9 y posteriores devuelven la ruta absoluta a __file__, independientemente de la ruta especificada en el comando python (o python3).

En el siguiente ejemplo, añadiremos el código al mismo archivo de script (file_path.py) en Python 3.7 y lo ejecutaremos en relación con el directorio anterior.

En Python 3.7, se utiliza la ruta absoluta. Los resultados se muestran al final de esta sección.

Obtiene el nombre del archivo y el nombre del directorio del archivo que se está ejecutando actualmente.

Para obtener el nombre del archivo y el nombre del directorio del archivo en ejecución, utilice la siguiente función en el módulo os.path de la biblioteca estándar.

  • os.path.basename()
  • os.path.dirname()
print('basename:    ', os.path.basename(__file__))
print('dirname:     ', os.path.dirname(__file__))

Resultado de la ejecución.

# basename:     file_path.py
# dirname:      data/src

Obtiene la ruta absoluta del archivo que se está ejecutando.

Si se obtiene una ruta relativa con __file__, puede convertirse en una ruta absoluta con os.path.abspath(). Los directorios también pueden obtenerse como rutas absolutas.

print('abspath:     ', os.path.abspath(__file__))
print('abs dirname: ', os.path.dirname(os.path.abspath(__file__)))

Resultado de la ejecución.

# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

Si se especifica una ruta absoluta en os.path.abspath(), se devolverá tal cual. Por lo tanto, si __file__ es una ruta absoluta, lo siguiente no causará un error.

  • os.path.abspath(__file__)

Lee otros archivos en función de la ubicación del archivo que se está ejecutando.

Si quiere leer otros archivos basándose en la ubicación (ruta) del archivo que se está ejecutando, una los siguientes dos archivos utilizando os.path.join().

  • Directorio del archivo que se ejecuta
  • Ruta relativa al archivo que se va a leer desde el archivo en ejecución.

Si quiere leer un archivo en el mismo directorio que el que está ejecutando, simplemente concatene el nombre del archivo.

print('[set target path 1]')
target_path_1 = os.path.join(os.path.dirname(__file__), 'target_1.txt')

print('target_path_1: ', target_path_1)

print('read target file:')
with open(target_path_1) as f:
    print(f.read())

Resultado de la ejecución.

# [set target path 1]
# target_path_1:  data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!

El nivel superior está representado por «. \». Puede dejarlo como está, pero puede utilizar os.path.normpath() para normalizar la ruta y eliminar los «. \» y otros caracteres.

print('[set target path 2]')
target_path_2 = os.path.join(os.path.dirname(__file__), '../dst/target_2.txt')

print('target_path_2: ', target_path_2)
print('normalize    : ', os.path.normpath(target_path_2))

print('read target file:')
with open(target_path_2) as f:
    print(f.read())

Resultado de la ejecución.

# [set target path 2]
# target_path_2:  data/src/../dst/target_2.txt
# normalize    :  data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Mueve el directorio actual al directorio del archivo que se está ejecutando.

Utilice os.chdir() para mover el directorio actual al directorio del archivo que se está ejecutando en el script.

Puedes ver que se mueve por os.getcwd().

print('[change directory]')
os.chdir(os.path.dirname(os.path.abspath(__file__)))
print('getcwd:      ', os.getcwd())

Resultado de la ejecución.

# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

Una vez que se ha movido el directorio actual, no es necesario concatenar con el directorio del archivo en ejecución al leer el archivo. Basta con especificar la ruta relativa al directorio del archivo en ejecución.

print('[set target path 1 (after chdir)]')
target_path_1 = 'target_1.txt'

print('target_path_1: ', target_path_1)

print('read target file:')
with open(target_path_1) as f:
    print(f.read())

print()
print('[set target path 2 (after chdir)]')
target_path_2 = '../dst/target_2.txt'

print('target_path_2: ', target_path_2)

print('read target file:')
with open(target_path_2) as f:
    print(f.read())

Resultado de la ejecución.

# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Se puede realizar el mismo procesamiento independientemente del directorio actual en tiempo de ejecución.

Como hemos demostrado, es posible cargar archivos en función de la ubicación del archivo de script, independientemente del directorio actual en tiempo de ejecución, utilizando uno de los siguientes métodos.

  • Concatenar el directorio del archivo en ejecución y la ruta relativa al archivo que se va a leer del archivo en ejecución utilizando os.path.join().
  • Mueve el directorio actual al directorio del archivo que se está ejecutando.

Es más fácil mover el directorio actual, pero por supuesto, si quieres leer o escribir más archivos después, tienes que tener en cuenta que el directorio actual ha sido movido.

Los resultados de los ejemplos anteriores se resumen a continuación.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     data/src/file_path.py
# basename:     file_path.py
# dirname:      data/src
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1]
# target_path_1:  data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2]
# target_path_2:  data/src/../dst/target_2.txt
# normalize    :  data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
# 
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

El resultado de especificar la ruta absoluta es el siguiente.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# basename:     file_path.py
# dirname:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1]
# target_path_1:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2]
# target_path_2:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/../dst/target_2.txt
# normalize    :  /Users/mbp/Documents/my-project/python-snippets/notebook/data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
# 
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

A continuación se muestra el resultado de mover el directorio actual en el terminal y ejecutar el mismo archivo de script. Se puede ver que se puede leer el mismo archivo aunque se ejecute desde una ubicación diferente.

cd data/src

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

python3 file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# __file__:     file_path.py
# basename:     file_path.py
# dirname:      
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2]
# target_path_2:  ../dst/target_2.txt
# normalize    :  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
# 
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Copied title and URL