Proverò ad affrontare alcune variazioni anche su questa domanda:
- trovare il percorso dello script chiamato
- trovare il percorso dello script attualmente in esecuzione
- trovare la directory dello script chiamato
(Alcune di queste domande sono state poste su SO, ma sono state chiuse come duplicati e reindirizzate qui.)
Avvertenze sull'uso __file__
Per un modulo che hai importato:
import something
something.__file__
restituirà il percorso assoluto del modulo. Tuttavia, dato lo script folowing foo.py:
#foo.py
print '__file__', __file__
Chiamandolo con 'python foo.py' tornerà semplicemente 'foo.py'. Se aggiungi un shebang:
#!/usr/bin/python
#foo.py
print '__file__', __file__
e chiamalo usando ./foo.py, restituirà './foo.py'. Chiamandolo da una directory diversa, (ad esempio metti foo.py nella barra delle directory), quindi chiamando uno dei due
python bar/foo.py
o aggiungendo uno shebang ed eseguendo direttamente il file:
bar/foo.py
restituirà 'bar / foo.py' (il percorso relativo ).
Trovare la directory
Ora andare da lì per ottenere la directory, os.path.dirname(__file__)
può anche essere complicato. Almeno sul mio sistema, restituisce una stringa vuota se la chiami dalla stessa directory del file. ex.
# foo.py
import os
print '__file__ is:', __file__
print 'os.path.dirname(__file__) is:', os.path.dirname(__file__)
produrrà:
__file__ is: foo.py
os.path.dirname(__file__) is:
In altre parole, restituisce una stringa vuota, quindi ciò non sembra affidabile se si desidera utilizzarlo per il file corrente (al contrario del file di un modulo importato). Per aggirare questo, puoi avvolgerlo in una chiamata a abspath:
# foo.py
import os
print 'os.path.abspath(__file__) is:', os.path.abspath(__file__)
print 'os.path.dirname(os.path.abspath(__file__)) is:', os.path.dirname(os.path.abspath(__file__))
che produce qualcosa di simile a:
os.path.abspath(__file__) is: /home/user/bar/foo.py
os.path.dirname(os.path.abspath(__file__)) is: /home/user/bar
Si noti che abspath () NON risolve i collegamenti simbolici. Se vuoi farlo, usa invece realpath (). Ad esempio, creare un link simbolico file_import_testing_link che punta a file_import_testing.py, con il seguente contenuto:
import os
print 'abspath(__file__)',os.path.abspath(__file__)
print 'realpath(__file__)',os.path.realpath(__file__)
l'esecuzione stamperà percorsi assoluti come:
abspath(__file__) /home/user/file_test_link
realpath(__file__) /home/user/file_test.py
file_import_testing_link -> file_import_testing.py
Usando inspect
@SummerBreeze menzioni utilizzando il ispezionare modulo.
Questo sembra funzionare bene, ed è abbastanza conciso, per i moduli importati:
import os
import inspect
print 'inspect.getfile(os) is:', inspect.getfile(os)
obbedientemente restituisce il percorso assoluto. Tuttavia, per trovare il percorso dello script attualmente in esecuzione, non ho visto un modo per usarlo.