Para obter a localização (caminho) de um ficheiro de script em execução em Python, utilizar __file__. Isto é útil para carregar outros ficheiros com base na localização do ficheiro em execução.
Até Python 3.8, __file__ retorna o caminho especificado ao executar o comando python (ou comando python3 em alguns ambientes). Se for especificado um caminho relativo, o caminho relativo é devolvido; se for especificado um caminho absoluto, o caminho absoluto é devolvido.
Em Python 3.9 e posteriores, o caminho absoluto é devolvido independentemente do caminho especificado em tempo de execução.
Os seguintes conteúdos são explicados.
os.getcwd()
,__file__
- Obter o nome do ficheiro e o nome do directório do ficheiro actualmente em execução.
- Obtenha o caminho absoluto do ficheiro a ser executado.
- Lê outros ficheiros com base na localização do ficheiro actualmente em execução.
- Mover o directório actual para o directório do ficheiro que está a ser executado.
- O mesmo processamento pode ser feito independentemente do directório actual em tempo de execução.
Ver o artigo seguinte para informações sobre como obter e alterar o directório actual (directório de trabalho).
- Artigos relacionados:Obter e alterar (mover) o directório actual em Python
Note-se que __file__ não pode ser utilizado em Jupyter Notebook (.ipynb).
O directório onde o .ipynb está localizado será executado como o directório actual, independentemente do directório onde o Jupyter Notebook é iniciado.
É possível utilizar os.chdir() no código para alterar o directório actual.
- os.getcwd() e __file__.
- Obter o nome do ficheiro e o nome do directório do ficheiro actualmente em execução.
- Obtenha o caminho absoluto do ficheiro a ser executado.
- Lê outros ficheiros com base na localização do ficheiro actualmente em execução.
- Mover o directório actual para o directório do ficheiro que está a ser executado.
- O mesmo processamento pode ser feito independentemente do directório actual em tempo de execução.
os.getcwd() e __file__.
No Windows, pode usar o comando dir em vez de pwd para verificar o directório actual.
pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook
Criar um ficheiro Python script (file_path.py) com os seguintes conteúdos no nível inferior (data\src).
import os
print('getcwd: ', os.getcwd())
print('__file__: ', __file__)
Executar o comando python (ou comando python3 em alguns ambientes) especificando o caminho para o ficheiro de script.
python3 data/src/file_path.py
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__: data/src/file_path.py
O caminho absoluto para o directório actual pode ser obtido com os.getcwd(). Pode também usar __file__ para obter o caminho especificado pelo comando python3.
Até Python 3.8, __file__ conterá o caminho especificado no comando python (ou python3). No exemplo acima, o caminho relativo é devolvido porque é relativo, mas o caminho absoluto é devolvido se for absoluto.
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 e mais tarde retorna o caminho absoluto para __file__, independentemente do caminho especificado no comando python (ou python3).
No exemplo seguinte, adicionaremos o código ao mesmo ficheiro de script (file_path.py) em Python 3.7 e executamo-lo em relação ao directório acima referido.
Em Python 3.7, o caminho absoluto é utilizado. Os resultados são mostrados no final desta secção.
Obter o nome do ficheiro e o nome do directório do ficheiro actualmente em execução.
Para obter o nome do ficheiro e o nome do directório do ficheiro em execução, utilize a seguinte função no módulo os.path da biblioteca padrão.
os.path.basename()
os.path.dirname()
print('basename: ', os.path.basename(__file__))
print('dirname: ', os.path.dirname(__file__))
Resultado da execução.
# basename: file_path.py
# dirname: data/src
Obtenha o caminho absoluto do ficheiro a ser executado.
Se um caminho relativo for obtido com __file__, pode ser convertido para um caminho absoluto com os.path.abspath(). Os directórios também podem ser obtidos como trajectórias absolutas.
print('abspath: ', os.path.abspath(__file__))
print('abs dirname: ', os.path.dirname(os.path.abspath(__file__)))
Resultado da execução.
# 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
Se um caminho absoluto for especificado em os.path.abspath(), ele será devolvido tal como está. Portanto, se __file__ for um caminho absoluto, o seguinte não causará um erro.
os.path.abspath(__file__)
Lê outros ficheiros com base na localização do ficheiro actualmente em execução.
Se quiser ler outros ficheiros com base na localização (caminho) do ficheiro a ser executado, junte os dois ficheiros seguintes usando os.path.join().
- Directório do ficheiro que está a ser executado
- Caminho relativo ao ficheiro a ser lido a partir do ficheiro em execução.
Se quiser ler um ficheiro no mesmo directório que o ficheiro que está a correr, basta concatenar o nome do ficheiro.
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 da execução.
# [set target path 1]
# target_path_1: data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
O nível superior é representado por “. \”. Pode deixá-lo como está, mas pode usar os.path.normpath() para normalizar o caminho e remover extra “. \” e outros 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 da execução.
# [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" !!
Mover o directório actual para o directório do ficheiro que está a ser executado.
Use os.chdir() para mover o directório actual para o directório do ficheiro a ser executado no script.
- Artigos relacionados:Obter e alterar (mover) o directório actual em Python
Pode ver que é movido por os.getcwd().
print('[change directory]')
os.chdir(os.path.dirname(os.path.abspath(__file__)))
print('getcwd: ', os.getcwd())
Resultado da execução.
# [change directory]
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
Uma vez movido o directório actual, não há necessidade de o concatenar com o directório do ficheiro em execução ao ler o ficheiro. Pode apenas especificar o caminho relativo ao directório do ficheiro em execução.
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 da execução.
# [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" !!
O mesmo processamento pode ser feito independentemente do directório actual em tempo de execução.
Como demonstrámos, é possível carregar ficheiros com base na localização do ficheiro de script, independentemente do directório actual em tempo de execução, utilizando um dos seguintes métodos.
- Concatenar o directório do ficheiro em execução e o caminho relativo ao ficheiro a ser lido do ficheiro em execução utilizando os.path.join().
- Mover o directório actual para o directório do ficheiro que está a ser executado.
É mais fácil mover o directório actual, mas claro que, se quiser ler ou escrever mais ficheiros depois disso, tem de ter em conta que o directório actual foi movido.
Os resultados dos exemplos anteriores são resumidos a seguir.
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" !!
O resultado da especificação do caminho absoluto é o seguinte.
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" !!
O resultado de mover o directório actual no terminal e executar o mesmo ficheiro de script é mostrado abaixo. É possível ver que o mesmo ficheiro pode ser lido mesmo que seja executado a partir de um local 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" !!