Actualización 2018-11-28:
Aquí hay un resumen de los experimentos con Python 2 y 3. Con
main.py: ejecuta foo.py
foo.py: ejecuta lib / bar.py
lib / bar.py: imprime expresiones de ruta de archivo
| 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__ |
Para Python 2, puede ser más claro cambiar a paquetes para poder usarlos from lib import bar
, simplemente agregue __init__.py
archivos vacíos a las dos carpetas.
Para Python 3, execfile
no existe; la alternativa más cercana es exec(open(<filename>).read())
, aunque esto afecta los marcos de la pila. Es más fácil de usar import foo
y import lib.bar
no se __init__.py
necesitan archivos.
Consulte también Diferencia entre importación y archivo de ejecución
Respuesta original
Aquí hay un experimento basado en las respuestas de este hilo, con Python 2.7.10 en Windows.
Los basados en la pila son los únicos que parecen dar resultados confiables. Los dos últimos tienen la sintaxis más corta , es decir:
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
¡Aquí se agrega a sys como funciones! Crédito a @Usagi y @pablog
Basado en los siguientes tres archivos, y ejecutando main.py desde su carpeta con python main.py
(también probé archivos ejecutables con rutas absolutas y llamadas desde una carpeta separada).
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__
absoluto o relativo?