2009-03-03 5 views
46

Supposons que j'ai deux modules:Comment obtenir le nom de fichier du module __main__ en Python?

a.py:

import b 
print __name__, __file__ 

b.py:

print __name__, __file__ 

je lance le fichier "a.py". Cette impression:

b  C:\path\to\code\b.py 
__main__ C:\path\to\code\a.py 

Question: comment puis-je obtenir le chemin vers le module __main__ (dans ce cas "a.py") à partir de la bibliothèque "b.py"?

Répondre

58
import __main__ 
print __main__.__file__ 
+1

Neat! Important de se rendre compte que l'on doit importer __main__ - j'ai fait une supposition au hasard et j'ai essayé la deuxième ligne, mais elle a échoué - maintenant je sais pourquoi. –

+17

'__main__' n'a pas toujours l'attribut' __file__'. – jfs

+0

Oui, ce serait bien si la réponse pouvait être mise à jour pour le mentionner. –

27

Peut-être que cela va faire l'affaire:

import sys 
from os import path 
print path.abspath(sys.modules['__main__'].__file__) 

Notez que, pour la sécurité, vous devriez vérifier si le module __main__ a un attribut __file__. Si elle est créée dynamiquement, ou vient d'être exécuté dans la console python interactif, il ne sera pas un __file__:

python 
>>> import sys 
>>> print sys.modules['__main__'] 
<module '__main__' (built-in)> 
>>> print sys.modules['__main__'].__file__ 
AttributeError: 'module' object has no attribute '__file__' 

Un chèque hasattr simple() fera l'affaire pour se prémunir contre le scénario 2, si c'est une possibilité dans votre application

+0

C'est le cas - merci! –

+0

Wunderbar! Je suis heureux d'avoir pu aider. Si cela répond à votre question, cela vous dérangerait-il de cliquer sur le bouton "Accepter" de la question? :-) –

+0

Si vous modifiez ceci pour utiliser le style "import __main__", je reviendrai à accepté, car il est plus détaillé que la nouvelle réponse acceptée. –

14

Le code python ci-dessous fournit des fonctionnalités supplémentaires, y compris qu'il fonctionne de manière transparente avec py2exe executables.

J'utilise un code similaire à celui-ci pour trouver les chemins relatifs au script en cours d'exécution, alias __main__. comme un avantage supplémentaire, il fonctionne multi-plateforme, y compris Windows.

import imp 
import os 
import sys 

def main_is_frozen(): 
    return (hasattr(sys, "frozen") or # new py2exe 
      hasattr(sys, "importers") # old py2exe 
      or imp.is_frozen("__main__")) # tools/freeze 

def get_main_dir(): 
    if main_is_frozen(): 
     # print 'Running from path', os.path.dirname(sys.executable) 
     return os.path.dirname(sys.executable) 
    return os.path.dirname(sys.argv[0]) 

# find path to where we are running 
path_to_script=get_main_dir() 

# OPTIONAL: 
# add the sibling 'lib' dir to our module search path 
lib_path = os.path.join(get_main_dir(), os.path.pardir, 'lib') 
sys.path.insert(0, lib_path) 

# OPTIONAL: 
# use info to find relative data files in 'data' subdir 
datafile1 = os.path.join(get_main_dir(), 'data', 'file1') 

Espérons que le code exemple ci-dessus peuvent fournir des informations supplémentaires sur la façon de déterminer le chemin du script en cours d'exécution ...

+1

Si vous changez de répertoire (avec 'os.chdir') entre le lancement le script et en appelant 'os.dirname (sys.argv [0])' le résultat est vide de sens. – RobM

+0

J'utilise pour faire un module 'GLOBALS.py', qui est au moins importé par le script principal, qui exécute quelque chose comme le code ci-dessus et stocke le résultat dans une variable' MAINDIR', donc je peux accéder 'GLOBALS.MAINDIR' à partir de tout autre module, sans se soucier de l'utilisation de 'os.chdir'. – Remi

+0

Si vous voulez connaître le répertoire de départ de votre script et que vous voulez également utiliser 'os.chdir()', vous devez sauvegarder l'initiale 'os.getcwd()'. Comme l'utilisateur était sur Windows, je voulais montrer quelque chose qui fonctionnerait aussi dans le contexte de py2exe et de freeze. – popcnt

1
import sys, os 

def getExecPath(): 
    try: 
     sFile = os.path.abspath(sys.modules['__main__'].__file__) 
    except: 
     sFile = sys.executable 
    return os.path.dirname(sFile) 

Cette fonction fonctionnera pour les programmes compilés Python et Cython.

6

Une autre méthode consisterait à utiliser sys.argv[0].

import os 
import sys 

main_file = os.path.realpath(sys.argv[0]) if sys.argv[0] else None 

sys.argv[0] sera une chaîne vide si Python obtient commencer par -c ou si elle est cochée depuis la console Python.

Questions connexes