J'ai une application qui réside dans un seul fichier .py. J'ai réussi à obtenir que pyInstaller l'intègre correctement dans un fichier EXE pour Windows. Le problème est que l'application nécessite un fichier .cfg qui se trouve toujours directement à côté de l'application dans le même répertoire.
Normalement, je construis le chemin en utilisant le code suivant:
import os
config_name = 'myapp.cfg'
config_path = os.path.join(sys.path[0], config_name)
Cependant, il semble que sys.path est vide lorsqu'il est appelé à partir d'un fichier EXE généré par pyInstaller. Ce même problème se produit lorsque vous exécutez la ligne de commande interactive python et essayez d’extraire sys.path [0].
Existe-t-il un moyen plus concret d’obtenir le chemin de l’application en cours afin que je puisse trouver les fichiers qui le concernent?
J'ai trouvé une solution. Vous devez vérifier si l'application s'exécute en tant que script ou en tant qu'exe figé:
import os
import sys
config_name = 'myapp.cfg'
# determine if application is a script file or frozen exe
if getattr(sys, 'frozen', False):
application_path = os.path.dirname(sys.executable)
Elif __file__:
application_path = os.path.dirname(__file__)
config_path = os.path.join(application_path, config_name)
Selon la documentation de pyInstaller, la méthode de récupération du chemin d’application suggérée est la suivante:
#!/usr/bin/python3
import sys, os
if getattr(sys, 'frozen', False):
# If the application is run as a bundle, the pyInstaller bootloader
# extends the sys module by a flag frozen=True and sets the app
# path into variable _MEIPASS'.
application_path = sys._MEIPASS
else:
application_path = os.path.dirname(os.path.abspath(__file__))
Testé pour pyInstaller v3.2, mais cela fonctionne certainement aussi pour les versions précédentes.
La solution de Soviut ne fonctionne pas, du moins pas en général pour les versions récentes de pyInstaller (notez que le PO a plusieurs années). Par exemple, sous MacOS, lorsque vous associez une application à un ensemble de fichiers unique, sys.executable
pointe uniquement sur l'emplacement de l'archive intégrée, qui est not l'emplacement où l'application est réellement exécutée après que le chargeur de démarrage pyInstaller a créé un fichier. environnement d'application temporaire. Seul sys._MEIPASS
pointe correctement vers cet emplacement. Reportez-vous à cette page de documentation pour plus d'informations sur le fonctionnement de pyInstaller.
J'ai raccourci le code un peu.
import os, sys
if getattr(sys, 'frozen', False):
application_path = os.path.dirname(sys.executable)
os.chdir(application_path)
logging.debug('CWD: ' + os.getcwd())
Mais sys._MEIPASS
a indiqué un mauvais répertoire. Je pense qu'il faut aussi sys._MEIPASS
+ \app_name
os.path.dirname(sys.argv[0])
Ça marche pour moi.
__file__
fonctionne à partir de la ligne de commande avec un exécutable python. Il donne également le nom du fichier de script sans le chemin réel en mode figé. Cependant, cela donne une erreur en mode interactif.
Ce qui suit fonctionnera pour les trois modes:
import sys,os
config_name = 'myapp.cfg'
if getattr(sys, 'frozen', False):
application_path = os.path.dirname(sys.executable)
running_mode = 'Frozen/executable'
else:
try:
app_full_path = os.path.realpath(__file__)
application_path = os.path.dirname(app_full_path)
running_mode = "Non-interactive (e.g. 'python myapp.py')"
except NameError:
application_path = os.getcwd()
running_mode = 'Interactive'
config_full_path = os.path.join(application_path, config_name)
print('Running mode:', running_mode)
print(' Appliction path :', application_path)
print(' Config full path :', config_full_path)
Sortie dans trois modes différents:
Running mode: Interactive
Appliction path : C:\Projects\MyAppDir
Config full path : C:\Projects\MyAppDir\myapp.cfg
C:\Projects\MyAppDir>myapp.exe
Running mode: Frozen/executable
Appliction path : C:\Program Files\myapp
Config full path : C:\Program Files\myapp\myapp.cfg
C:\Projects\MyAppDir>python myapp.py
Running mode: Non-interactive (e.g. 'python myapp.py')
Appliction path : C:\Projects\MyAppDir
Config full path : C:\Projects\MyAppDir\myapp.cfg
C:\Projects\MyAppDir>
Beaucoup de réponses ici mais j'ai trouvé cette solution fonctionne dans la plupart des situations:
import os
import sys
import os.path as op
try:
this_file = __file__
except NameError:
this_file = sys.argv[0]
this_file = op.abspath(this_file)
if getattr(sys, 'frozen', False):
application_path = getattr(sys, '_MEIPASS', op.dirname(sys.executable))
else:
application_path = op.dirname(this_file)