Comment puis-je obtenir le chemin d'accès et nom du fichier qui est en cours d'exécution?

j'ai des scripts appelant d'autres fichiers de script mais j'ai besoin d'obtenir le chemin de fichier du fichier qui est actuellement en cours d'exécution dans le processus.

Par exemple, disons que j'ai trois fichiers. En utilisant execfile :

  • script_1.py appels script_2.py .
  • à son tour, script_2.py appelle script_3.py .

Comment puis-je obtenir le nom de fichier et le chemin script_3.py , de code dans script_3.py , sans avoir à passer cette information comme arguments de script_2.py ?

(L'exécution os.getcwd() renvoie le chemin de fichier du script de départ original et non celui du fichier courant.)

386
demandé sur kdopen 2008-09-08 23:41:10
la source

23 ответов

p1.py:

execfile("p2.py")

p2.py:

import inspect, os
print inspect.getfile(inspect.currentframe()) # script filename (usually with path)
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # script directory
217
répondu Pat Notz 2012-08-26 01:57:31
la source
__file__

comme d'autres l'ont dit. Vous pouvez également utiliser os.chemin.realpath pour éliminer symlinks:

import os

os.path.realpath(__file__)
476
répondu user13993 2018-02-20 06:11:21
la source

Voici une expérience basée sur les réponses dans ce thread - avec Python 2.7.10 sur Windows.

La pile, ceux sont les seuls qui semblent donner des résultats fiables. Les deux derniers ont la syntaxe la plus courte , ie -

print os.path.abspath(inspect.stack()[0][1])                   # C:\testpath\lib\script3.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1]))  # C:\testpath\lib

c'est pour ceux-ci étant ajoutés à sys comme des fonctions! Crédit à @Usagi et @pablog

Basé sur les trois fichiers suivants, et en cours d'exécution script1.py de son dossier avec python script1.py (également essayé exécufiles avec des chemins absolus et appel à partir d'un dossier séparé).

C:\testpath\script1.py: execfile('script2.py')

C:\testpath\script2.py: execfile('lib/script3.py')

C:\testpath\lib\script3.py:

import sys
import os
import inspect

print "Python " + sys.version
print

print __file__                                        # script1.py
print sys.argv[0]                                     # script1.py
print inspect.stack()[0][1]                           # lib/script3.py
print sys.path[0]                                     # C:\testpath
print

print os.path.realpath(__file__)                      # C:\testpath\script1.py
print os.path.abspath(__file__)                       # C:\testpath\script1.py
print os.path.basename(__file__)                      # script1.py
print os.path.basename(os.path.realpath(sys.argv[0])) # script1.py
print

print sys.path[0]                                     # C:\testpath
print os.path.abspath(os.path.split(sys.argv[0])[0])  # C:\testpath
print os.path.dirname(os.path.abspath(__file__))      # C:\testpath
print os.path.dirname(os.path.realpath(sys.argv[0]))  # C:\testpath
print os.path.dirname(__file__)                       # (empty string)
print

print inspect.getfile(inspect.currentframe())         # lib/script3.py

print os.path.abspath(inspect.getfile(inspect.currentframe())) # C:\testpath\lib\script3.py
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # C:\testpath\lib
print

print os.path.abspath(inspect.stack()[0][1])          # C:\testpath\lib\script3.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1]))  # C:\testpath\lib
print
69
répondu Brian Burns 2015-12-02 01:59:17
la source

je pense que c'est plus propre:

import inspect
print inspect.stack()[0][1]

et obtient les mêmes informations que:

print inspect.getfile(inspect.currentframe())

où [0] est la trame courante dans la pile (en haut de la pile) et [1] est pour le nom du fichier, l'augmentation pour revenir en arrière dans la pile i.e.

print inspect.stack()[1][1]

serait le nom du fichier du script qui a appelé le cadre courant. En outre, l'utilisation de [-1] vous mènera au bas de la pile, le script d'appel original.

61
répondu Usagi 2012-03-30 20:37:10
la source

les suggestions indiquées comme étant les meilleures sont toutes vraies si votre script se compose d'un seul fichier.

si vous voulez connaître le nom de l'exécutable (c.-à-d. le fichier racine passé à l'interpréteur python pour le programme courant) à partir d'un fichier qui peut être importé en tant que module, vous devez le faire (supposons que c'est dans un fichier nommé foo.py ):

import inspect

print inspect.stack()[-1][1]

parce que la dernière chose ( [-1] ) sur la pile est la première chose qui y est entrée (Les piles sont des structures de données LIFO/FILO).

puis dans le fichier bar.py si vous import foo il imprimera bar.py , plutôt que foo.py , qui serait la valeur de tous ces:

  • __file__
  • inspect.getfile(inspect.currentframe())
  • inspect.stack()[0][1]
35
répondu 2010-03-01 23:02:35
la source
import os
os.path.dirname(__file__) # relative directory path
os.path.abspath(__file__) # absolute file path
os.path.basename(__file__) # the file name only
35
répondu Neal Xiong 2015-02-06 04:05:18
la source
import os
print os.path.basename(__file__)

cela nous donnera le nom du fichier seulement. c'est-à-dire si abspath of file est c:\abcd\abc.py alors la 2e ligne s'affichera abc.py

13
répondu vishal ekhe 2013-08-11 07:05:05
la source

ce n'est pas tout à fait clair ce que vous voulez dire par"le chemin du fichier qui est actuellement en cours d'exécution dans le processus". sys.argv[0] contient habituellement l'emplacement du script qui a été invoqué par L'interpréteur Python. Consultez la documentation sys pour plus de détails.

comme @Tim et @Pat Notz L'ont fait remarquer, l'attribut _ _ file _ _ donne accès à

le fichier à partir duquel le module a été charger, s'il a été chargé à partir d'un fichier

11
répondu Blair Conrad 2014-09-06 09:16:10
la source

j'ai un script qui doit fonctionner sous environnement windows. C'est ce code que j'ai terminé avec:

import os,sys
PROJECT_PATH = os.path.abspath(os.path.split(sys.argv[0])[0])

c'est une sacrée décision. Mais il ne nécessite pas de bibliothèques externes et c'est la chose la plus importante dans mon cas.

9
répondu garmoncheg 2015-06-14 19:39:43
la source

l'attribut __file__ fonctionne aussi bien pour le fichier contenant le code d'exécution principal que pour les modules importés.

voir https://web.archive.org/web/20090918095828/http://pyref.infogami.com/__file _ _ _

8
répondu Readonly 2015-08-07 02:59:48
la source
import os
os.path.dirname(os.path.abspath(__file__))

pas besoin d'inspecter ou toute autre bibliothèque.

cela a fonctionné pour moi quand j'ai dû importer un script (à partir d'un répertoire différent puis le script exécuté), qui utilisait un fichier de configuration résidant dans le même dossier que le script importé.

6
répondu Kwuite 2014-06-24 19:21:18
la source
import sys

print sys.path[0]

cela imprimerait le chemin du script en cours d'exécution

5
répondu appusajeev 2010-01-02 21:34:55
la source

je pense que c'est juste __file__ sonne comme vous pouvez également vouloir vérifier le module d'inspection .

5
répondu Pat Notz 2015-05-24 22:51:39
la source

vous pouvez utiliser inspect.stack()

import inspect,os
inspect.stack()[0]  => (<frame object at 0x00AC2AC0>, 'g:\Python\Test\_GetCurrentProgram.py', 15, '<module>', ['print inspect.stack()[0]\n'], 0)
os.path.abspath (inspect.stack()[0][1]) => 'g:\Python\Test\_GetCurrentProgram.py'
4
répondu PabloG 2015-06-14 19:40:59
la source
import sys
print sys.argv[0]
3
répondu WBAR 2010-04-19 11:47:21
la source

cela devrait fonctionner:

import os,sys
filename=os.path.basename(os.path.realpath(sys.argv[0]))
dirname=os.path.dirname(os.path.realpath(sys.argv[0]))
2
répondu Jahid 2015-06-14 19:37:44
la source

pour obtenir le répertoire d'exécution du script

 print os.path.dirname( inspect.getfile(inspect.currentframe()))
1
répondu pbaranski 2017-05-10 13:51:15
la source

Pour garder la migration de la cohérence entre les plates-formes (macOS/Windows/Linux), essayez:

path = r'%s' % os.getcwd().replace('\','/')

1
répondu Qiao Zhang 2018-04-12 10:37:24
la source

j'ai utilisé l'approche par __fichier__

os.path.abspath(__file__)

mais il y a un petit truc, il renvoie le .fichier py quand le code est lancé la première fois, exécute ensuite donner le nom de *.dossier pyc

alors je suis resté avec:

inspect.getfile(inspect.currentframe())

ou

sys._getframe().f_code.co_filename

0
répondu mik80 2011-03-01 12:23:09
la source

j'ai écrit une fonction qui tiennent compte de l'éclipse débogueur et unittest . Il renvoie le dossier du premier script que vous lancez. Vous pouvez éventuellement spécifier le fichier __fichier__ _ var, mais l'essentiel est que vous n'avez pas à partager cette variable à travers toute votre appelant la hiérarchie .

peut-être que vous pouvez gérer d'autres empiler des cas particuliers que je n'ai pas vu, mais pour moi c'est OK.

import inspect, os
def getRootDirectory(_file_=None):
    """
    Get the directory of the root execution file
    Can help: /q/how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executing-50544/"""
    # If we don't have the __file__ :
    if _file_ is None:
        # We get the last :
        rootFile = inspect.stack()[-1][1]
        folder = os.path.abspath(rootFile)
        # If we use unittest :
        if ("/pysrc" in folder) & ("org.python.pydev" in folder):
            previous = None
            # We search from left to right the case.py :
            for el in inspect.stack():
                currentFile = os.path.abspath(el[1])
                if ("unittest/case.py" in currentFile) | ("org.python.pydev" in currentFile):
                    break
                previous = currentFile
            folder = previous
        # We return the folder :
        return os.path.dirname(folder)
    else:
        # We return the folder according to specified __file__ :
        return os.path.dirname(os.path.realpath(_file_))
0
répondu hayj 2016-06-14 18:57:41
la source

la manière la plus simple est:

in script_1.py:

import subprocess
subprocess.call(['python3',<path_to_script_2.py>])

in script_2.py:

sys.argv[0]

P. S.: j'ai essayé execfile , mais puisqu'il lit script_2.py comme une chaîne, sys.argv[0] retourné <string> .

0
répondu Lucas Azevedo 2018-06-08 15:29:47
la source
import os

import wx


# return the full path of this file
print(os.getcwd())

icon = wx.Icon(os.getcwd() + '/img/image.png', wx.BITMAP_TYPE_PNG, 16, 16)

# put the icon on the frame
self.SetIcon(icon)
-1
répondu jscabuzzo 2015-06-27 03:34:11
la source

si vous voulez juste le nom du fichier sans ./ ou .py vous pouvez essayer ce

filename = testscript.py
file_name = __file__[2:-3]

file_name imprimera testscript vous pouvez générer ce que vous voulez en changeant l'index à l'intérieur []

-2
répondu sapam 2013-01-21 01:14:53
la source

Autres questions sur python scripting file