Skip to content

Ottenere il percorso del file corrente (script) in Python: __file__

Python

In Python, puoi ottenere il percorso (posizione) del file corrente, ovvero il file di script attualmente in esecuzione (.py) con __file__. __file__ è utile per leggere altri file in base alla posizione del file corrente.

In Python 3.8 e versioni precedenti, __file__ richiede il percorso specificato durante l’esecuzione del comando python (o python3). Se si specifica un percorso relativo, viene generato un percorso relativo. Se si specifica un percorso assoluto, viene restituito un percorso assoluto.

In Python 3.9 e versioni successive, __file__ viene rilasciato sempre un percorso assoluto, con il comando dal fatto che il percorso specificato python sia relativo o assoluto.

In questo articolo vengono descritti i seguenti contenuti.

  • os.getcwd() e __file__
  • Ottieni il nome del file e della directory del file di script corrente
  • Ottieni il percorso assoluto del file di script corrente
  • Leggi altri file in base alla posizione del file di script corrente
  • Modificare la directory corrente nella directory del file di script corrente
  • Legge lo stesso file nella directory di lavoro corrente

Vedere il seguente articolo su come ottenere e la directory di lavoro corrente.

Si noti che __file__ non può essere utilizzato in Jupyter Notebook (.ipynb). In dalla directory in cui è stato avviato Jupyter Notebook, la directory avviata è dove si trova .ipynb. È possibile modificare la directory corrente utilizzando os.chdir() nel codice.

os.getcwd() e __file__

Supponiamo di lavorare nella directory seguente. Su Windows, puoi controllare la directory corrente con il comando dir invece di pwd.

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

Crea un file di script Python (file_path.py) con il seguente codice nella directory inferiore (data/src).

import os

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

Eseguilo con il comando python (o python3).

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

Puoi ottenere il percorso assoluto della directory di lavoro corrente con os.getcwd() e il percorso specificato con il comando python3 con __file__.

In Python 3.8 e precedenti, il percorso specificato dal comando python (o python3) è archiviato in __file__. Nell’esempio precedente, viene specificato un percorso relativo, quindi viene restituito un percorso relativo, ma se viene specificato un percorso assoluto, viene restituito un percorso 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

In Python 3.9 e versioni successive, __file__ memorizzato per un percorso assoluto, con il comando se dal fatto che il percorso specificato python sia relativo o assoluto.

Negli esempi seguenti, aggiungi codice allo stesso file di script (file_path.py) ed esegui dalla stessa directory dell’esempio precedente in Python3.7.

Nota che se __file__ è un percorso assoluto (quando Python 3.9 o successivo, o quando specifichi il percorso assoluto in Python 3.8 o precedente), puoi usare lo stesso codice descritto di seguito per leggere altri file in base alla posizione del file di script corrente . I risultati dell’esecuzione specificando il percorso assoluto in Python3.7 sono mostrati alla fine.

Ottieni il nome del file e della directory del file di script corrente

Utilizzare os.path.basename() e os.path.dirname() per ottenere il nome del file e della directory del file di script corrente.

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

Il risultato è il seguente.

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

Se vuoi ottenere solo il nome della directory direttamente sopra il file, usa os.path.basename(os.path.dirname(__file__)).

Vedere il seguente articolo per i dettagli su os.path.basename(), os.path.dirname(), ecc.

Ottieni il percorso assoluto del file di script corrente

Se ottieni il percorso relativo con __file__, puoi convertirlo in un percorso assoluto con os.path.abspath().

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

Il risultato è il seguente.

# 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 si specifica un percorso assoluto in os.path.abspath(), verrà restituito così com’è, quindi se __file__ è un percorso assoluto, non verrà generato alcun errore anche se si imposta os.path.abspath(__file__).

Leggi altri file in base alla posizione del file di script corrente

Se vuoi leggere altri file in base alla posizione (percorso) del file di script corrente, unisci il percorso della directory del file corrente e il percorso relativo (dal file corrente) del file che vuoi leggere con os.path. giuntura().

Si noti che i file nella stessa directory del file di script possono essere letti specificando solo 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())

Il risultato è il seguente.

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

La directory superiore è rappresentata da ../. Non ci sono problemi così com’è, ma se usi os.path.normpath(), puoi normalizzare il percorso e rimuovere extra ../, ecc.

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())

Il risultato è il seguente.

# [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" !!

Modificare la directory corrente nella directory del file di script corrente

Utilizzare os.chdir() per la directory di lavoro corrente nella directory del file di script corrente.

Puoi confermare che è stato modificato con os.getcwd().

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

Il risultato è il seguente.

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

Se la directory di lavoro corrente è la stessa della directory del file corrente, è possibile specificare un percorso relativo dal file corrente per leggere altri file.

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())

Il risultato è il seguente.

# [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" !!

Legge lo stesso file nella directory di lavoro corrente

Utilizzando __file__ per ottenere il percorso del lavoro corrente di script, è possibile leggere lo stesso file nella directory di corrente.

Come mostrato finora, ci sono due modi:

  • Unisciti alla directory __file__ e al relativo percorso (da __file__) del file che vuoi leggere con os.path.join().
  • Modifica la directory di lavoro corrente nella directory __file__.

È più facile cambiare la directory corrente, ma ovviamente, se leggi o scrivi file in seguito, devi considerare che la directory corrente è stata cambiata.

Il risultato degli esempi finora è il seguente.

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 per la specifica del percorso assoluto con il comando python3 è il seguente. Puoi leggere lo stesso file.

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" !!

Modificare la directory corrente nel terminale ed eseguire lo stesso file di script. Puoi vedere che lo stesso file viene letto da posizioni diverse.

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" !!