2010-02-18 14 views
15

Puedo usar este fragmento de código en mi script para determinar, de una manera multiplataforma, dónde exactamente está siendo ejecutado desde:¿cómo puedo obtener el directorio actual del ejecutable en py2exe?

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

bastante simple. Luego sigo usando SCRIPT_ROOT en otras áreas de mi script para asegurarme de que todo esté correctamente relacionado. 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 solucionarlo o solucionarlo?

+0

Hay una pregunta duplicada anterior pero con menos respuestas: [Determinando la ruta de la aplicación en un EXE Python generado por pyInstaller] (http://stackoverflow.com/questions/404744) – olibre

Respuesta

2

Prueba esto:

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

En mi experiencia, usando 'sys.argv [ 0] 'no tiene una ruta cuando el programa se encuentra a través de la variable PATH. – Ber

+0

@Ber, ... sin embargo, 'py2exe' es un caso especial, y lo establece a un valor totalmente calificado en todos los casos. –

20

Aquí es el py2exe documentation reference y aquí están los artículos pertinentes:

  • sys.executable se establece en la ruta completa del archivo EXE.
  • El primer elemento en sys.argv es la ruta de acceso completa del ejecutable, el resto son los argumentos de la línea de comandos.
  • 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 lugar)

No se desprende de dichos documentos ya sea "el archivo EXE" y "ejecutable" son la misma cosa , y por lo tanto si sys.executable y sys.argv[0] son lo mismo. En cuanto a código que trabajó tanto para script.py y py2exe_executable.exe última vez que tuve que hacer esto, me parece algo así como:

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

Como digo que funcionó, pero no recuerdo por qué pensé que fue necesario en lugar de solo usar sys.argv[0].

El uso solo de 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 hice una prueba; conjeturas de golpes y pontificación de 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] ))) 

=== configuración.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 
+0

Creo que sys.executable generalmente apunta al intérprete python, que es lo que quiere bajo py2exe, pero no de otra manera. – prestomation

+0

@prestomation: ¿Qué es "el intérprete de Python en sí" en el caso py2exe? ¿A qué te refieres con "pero no de otra manera"? –

+0

"de lo contrario" es cuando está ejecutando un archivo interpretado, que es la mayoría de los entornos. En el caso py2exe, me imagino que el intérprete es tu py2exe, porque está incluido. Parece que tu edición más reciente confirma eso. – prestomation

8

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

El PO solicitó una versión para py2exe de:

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

La mejor respuesta es determinar si python está congelado en un exe, py2exe tiene docum entación en 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() 

Puesto que, la pitón es EAFP, aquí está una versión 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__)) 

Salud!

+0

@Ber, tiene usted razón ... Debería haber leído más detenidamente. ¿Mejor? – VertigoRay

+1

Esto es EXACTAMENTE lo que la pregunta solicitó. Gracias por la gran solución. –

Cuestiones relacionadas