script py3exe compile python py2exe

python - py3exe - ¿Cómo puedo obtener el directorio actual del ejecutable en py2exe?



python 3.7 to exe (3)

Utilizo este bit de código en mi script para señalar, de forma multiplataforma, desde donde se ejecuta exactamente:

SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))

Bastante simple. Luego continúo usando SCRIPT_ROOT en otras áreas de mi script para asegurarme de que todo sea correctamente relativo. Mi problema ocurre cuando lo ejecuto a través de py2exe, porque el ejecutable generado no establece __file__ , por lo tanto, mi script se rompe. ¿Alguien sabe cómo solucionar o solucionar esto?


Aquí está la referencia de documentación de py2exe y aquí están los elementos relevantes:

  • sys.executable se establece en la ruta completa del archivo exe.
  • El primer elemento en sys.argv es la ruta completa del ejecutable, el resto son los argumentos de la línea de comando.
  • sys.frozen solo existe en el ejecutable. Se establece en "console_exe" para un ejecutable de consola, en "windows_exe" para un ejecutable gui sin consola y en "dll" para un servidor dll en proceso.
  • __file__ no está definido (es posible que desee utilizar sys.argv [0] en su lugar)

No se desprende de esos documentos si "el archivo exe" y "el ejecutable" son la misma cosa, y por lo tanto si sys.executable y sys.argv[0] son la misma cosa. Mirando el código que funcionó para script.py y py2exe_executable.exe la última vez que tuve que hacer esto, encontré algo como:

if hasattr(sys, ''frozen''): basis = sys.executable else: basis = sys.argv[0] required_folder = os.path.split(basis)[0]

Como dije, eso funcionó, pero no recuerdo por qué pensé que era necesario en lugar de simplemente usar sys.argv[0] .

Usar solo la basis fue adecuado para el trabajo en cuestión (lea los archivos en ese directorio). Para un registro más permanente, divida algo como os.path.realpath(basis) .

Actualización En realidad hizo una prueba; Supera las conjeturas y la pontificación del sillón :-)

Resumen: Ignore sys.frozen, ignore sys.executable, vaya con sys.argv [0] incondicionalmente.

Evidencia:

=== foo.py ===

# coding: ascii import sys, os.path print ''sys has frozen:'', hasattr(sys, ''frozen'') print ''using sys.executable:'', repr(os.path.dirname(os.path.realpath(sys.executable))) print ''using sys.argv[0]:'', repr(os.path.dirname(os.path.realpath(sys.argv[0] )))

=== setup.py ===

from distutils.core import setup import py2exe setup(console=[''foo.py''])

=== resultados ===

C:/junk/so/py2exe>/python26/python foo.py sys has frozen: False using sys.executable: ''C://python26'' using sys.argv[0]: ''C://junk//so//py2exe'' # where foo.py lives C:/junk/so/py2exe>dist/foo sys has frozen: True using sys.executable: ''C://junk//so//py2exe//dist'' using sys.argv[0]: ''C://junk//so//py2exe//dist'' # where foo.exe lives


Prueba esto:

import os import sys os.path.realpath(os.path.dirname(sys.argv[0]))


Py2exe no define __file__ : http://www.py2exe.org/index.cgi/Py2exeEnvironment

El OP solicitó una versión amigable de py2exe de:

SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))

La mejor respuesta es determinar si Python está congelado en un archivo ejecutable, py2exe tiene documentación sobre esto: http://www.py2exe.org/index.cgi/HowToDetermineIfRunningFromExe

import imp, os, 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(): return os.path.dirname(sys.executable) return os.path.dirname(os.path.realpath(__file__)) SCRIPT_ROOT = get_main_dir()

Dado que, el python es EAFP , aquí hay una versión de EAFP ...

try: if sys.frozen or sys.importers: SCRIPT_ROOT = os.path.dirname(sys.executable) except AttributeError: SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))

¡Aclamaciones!