Aggiornamento 28-11-2018:
Ecco un riassunto degli esperimenti con Python 2 e 3. Con
main.py - esegue foo.py
foo.py - esegue lib / bar.py
lib / bar.py - stampa le espressioni del percorso file
| Python | Run statement | Filepath expression |
|--------+---------------------+----------------------------------------|
| 2 | execfile | os.path.abspath(inspect.stack()[0][1]) |
| 2 | from lib import bar | __file__ |
| 3 | exec | (wasn't able to obtain it) |
| 3 | import lib.bar | __file__ |
Per Python 2, potrebbe essere più chiaro passare ai pacchetti in modo da poterlo usare from lib import bar
- basta aggiungere __init__.py
file vuoti alle due cartelle.
Per Python 3, execfile
non esiste: l'alternativa più vicina è exec(open(<filename>).read())
, sebbene ciò influisca sui frame dello stack. È più semplice da usare import foo
e import lib.bar
non è __init__.py
necessario alcun file.
Vedi anche Differenza tra import ed execfile
Risposta originale:
Ecco un esperimento basato sulle risposte in questo thread - con Python 2.7.10 su Windows.
Quelli basati sullo stack sono gli unici che sembrano dare risultati affidabili. Gli ultimi due hanno la sintassi più breve , ovvero -
print os.path.abspath(inspect.stack()[0][1]) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1])) # C:\filepaths\lib
Ecco a questi che vengono aggiunti al sistema come funzioni! Ringraziamo @Usagi e @pablog
Basato sui seguenti tre file, ed eseguendo main.py dalla sua cartella con python main.py
(ho anche provato gli eseguibili con percorsi assoluti e chiamando da una cartella separata).
C: \ filepaths \ main.py: execfile('foo.py')
C: \ filepaths \ foo.py: execfile('lib/bar.py')
C: \ filepaths \ lib \ bar.py:
import sys
import os
import inspect
print "Python " + sys.version
print
print __file__ # main.py
print sys.argv[0] # main.py
print inspect.stack()[0][1] # lib/bar.py
print sys.path[0] # C:\filepaths
print
print os.path.realpath(__file__) # C:\filepaths\main.py
print os.path.abspath(__file__) # C:\filepaths\main.py
print os.path.basename(__file__) # main.py
print os.path.basename(os.path.realpath(sys.argv[0])) # main.py
print
print sys.path[0] # C:\filepaths
print os.path.abspath(os.path.split(sys.argv[0])[0]) # C:\filepaths
print os.path.dirname(os.path.abspath(__file__)) # C:\filepaths
print os.path.dirname(os.path.realpath(sys.argv[0])) # C:\filepaths
print os.path.dirname(__file__) # (empty string)
print
print inspect.getfile(inspect.currentframe()) # lib/bar.py
print os.path.abspath(inspect.getfile(inspect.currentframe())) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # C:\filepaths\lib
print
print os.path.abspath(inspect.stack()[0][1]) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1])) # C:\filepaths\lib
print
__file__
assoluto o relativo?