Per ottenere la posizione (percorso) di un file di script in esecuzione in Python, usate __file__. Questo è utile per caricare altri file in base alla posizione del file in esecuzione.
Fino a Python 3.8, __file__ restituisce il percorso specificato durante l'esecuzione del comando python (o comando python3 in alcuni ambienti). Se viene specificato un percorso relativo, viene restituito il percorso relativo; se viene specificato un percorso assoluto, viene restituito il percorso assoluto.
In Python 3.9 e successivi, il percorso assoluto viene restituito indipendentemente dal percorso specificato a runtime.
Vengono spiegati i seguenti contenuti.
os.getcwd()
,__file__
- Ottiene il nome del file e della directory del file attualmente in esecuzione.
- Ottiene il percorso assoluto del file in esecuzione.
- Legge altri file in base alla posizione del file in esecuzione.
- Sposta la directory corrente nella directory del file in esecuzione.
- La stessa elaborazione può essere fatta indipendentemente dalla directory corrente in fase di esecuzione.
Vedi il seguente articolo per informazioni su come ottenere e cambiare la directory corrente (directory di lavoro).
- Articoli correlati:Ottenere e cambiare (spostare) la directory corrente in Python
Si noti che __file__ non può essere usato in Jupyter Notebook (.ipynb).
La directory in cui si trova .ipynb sarà eseguita come directory corrente, indipendentemente dalla directory in cui Jupyter Notebook è avviato.
È possibile usare os.chdir() nel codice per cambiare la directory corrente.
- os.getcwd() e __file__.
- Ottiene il nome del file e della directory del file attualmente in esecuzione.
- Ottiene il percorso assoluto del file in esecuzione.
- Legge altri file in base alla posizione del file in esecuzione.
- Sposta la directory corrente nella directory del file in esecuzione.
- La stessa elaborazione può essere fatta indipendentemente dalla directory corrente in fase di esecuzione.
os.getcwd() e __file__.
In Windows, potete usare il comando dir invece di pwd per controllare la directory corrente.
pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook
Create un file di script Python (file_path.py) con il seguente contenuto nel livello inferiore (data\src).
import os
print('getcwd: ', os.getcwd())
print('__file__: ', __file__)
Eseguite il comando python (o il comando python3 in alcuni ambienti) specificando il percorso del file di script.
python3 data/src/file_path.py
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__: data/src/file_path.py
Il percorso assoluto della directory corrente può essere ottenuto con os.getcwd(). Potete anche usare __file__ per ottenere il percorso specificato dal comando python3.
Fino a Python 3.8, __file__ conterrà il percorso specificato nel comando python (o python3). Nell'esempio sopra, il percorso relativo viene restituito perché è relativo, ma il percorso assoluto viene restituito se è assoluto.
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 successivi restituisce il percorso assoluto a __file__, indipendentemente dal percorso specificato nel comando python (o python3).
Nell'esempio seguente, aggiungeremo il codice allo stesso file di script (file_path.py) in Python 3.7 e lo eseguiremo relativo alla directory di cui sopra.
In Python 3.7, viene usato il percorso assoluto. I risultati sono mostrati alla fine di questa sezione.
Ottiene il nome del file e della directory del file attualmente in esecuzione.
Per ottenere il nome del file e della directory del file in esecuzione, usate la seguente funzione nel modulo os.path della libreria standard.
os.path.basename()
os.path.dirname()
print('basename: ', os.path.basename(__file__))
print('dirname: ', os.path.dirname(__file__))
Risultato dell'esecuzione.
# basename: file_path.py
# dirname: data/src
Ottiene il percorso assoluto del file in esecuzione.
Se un percorso relativo è ottenuto con __file__, può essere convertito in un percorso assoluto con os.path.abspath(). Anche le directory possono essere ottenute come percorsi assoluti.
print('abspath: ', os.path.abspath(__file__))
print('abs dirname: ', os.path.dirname(os.path.abspath(__file__)))
Risultato dell'esecuzione.
# 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 un percorso assoluto è specificato in os.path.abspath(), sarà restituito così com'è. Pertanto, se __file__ è un percorso assoluto, quanto segue non causerà un errore.
os.path.abspath(__file__)
Legge altri file in base alla posizione del file in esecuzione.
Se volete leggere altri file in base alla posizione (percorso) del file in esecuzione, unite i seguenti due file usando os.path.join().
- Directory del file in esecuzione
- Percorso relativo al file da leggere dal file in esecuzione.
Se volete leggere un file nella stessa directory del file che state eseguendo, basta concatenare il nome del file.
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())
Risultato dell'esecuzione.
# [set target path 1]
# target_path_1: data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
Il livello superiore è rappresentato da “. \”. Potete lasciarlo così com'è, ma potete usare os.path.normpath() per normalizzare il percorso e rimuovere gli extra “. \” e altri caratteri.
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())
Risultato dell'esecuzione.
# [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" !!
Sposta la directory corrente nella directory del file in esecuzione.
Usate os.chdir() per spostare la directory corrente nella directory del file che viene eseguito nello script.
- Articoli correlati:Ottenere e cambiare (spostare) la directory corrente in Python
Potete vedere che è spostato da os.getcwd().
print('[change directory]')
os.chdir(os.path.dirname(os.path.abspath(__file__)))
print('getcwd: ', os.getcwd())
Risultato dell'esecuzione.
# [change directory]
# getcwd: /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
Una volta che la directory corrente è stata spostata, non c'è bisogno di concatenarla con la directory del file in esecuzione quando si legge il file. Potete semplicemente specificare il percorso relativo alla directory del file in esecuzione.
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())
Risultato dell'esecuzione.
# [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" !!
La stessa elaborazione può essere fatta indipendentemente dalla directory corrente in fase di esecuzione.
Come abbiamo mostrato, è possibile caricare i file in base alla posizione del file di script, indipendentemente dalla directory corrente in fase di esecuzione, utilizzando uno dei seguenti metodi.
- Concatena la directory del file in esecuzione e il percorso relativo al file da leggere dal file in esecuzione usando os.path.join().
- Sposta la directory corrente nella directory del file in esecuzione.
È più facile spostare la directory corrente, ma naturalmente, se volete leggere o scrivere altri file dopo, dovete tenere conto che la directory corrente è stata spostata.
I risultati degli esempi precedenti sono riassunti di seguito.
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" !!
Il risultato di specificare il percorso assoluto è il seguente.
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" !!
Il risultato dello spostamento della directory corrente nel terminale e dell'esecuzione dello stesso file di script è mostrato qui sotto. Potete vedere che lo stesso file può essere letto anche se viene eseguito da una posizione diversa.
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" !!