Лучший способ вызвать скрипты подпроцесса в Python exe - PullRequest
1 голос
/ 12 июня 2019

В настоящее время я пытаюсь создать кроссплатформенный exe-файл Python, основанный на вызове других скриптов Python и R.Одна проблема, с которой я столкнулся, заключалась в том, что мой exe-файл ожидал, что мои файлы сценариев будут в корневом каталоге, а не в каталоге, где находится мой exe-файл.Мне удалось это исправить, выполнив следующие действия:

   if getattr(sys, 'frozen', False):
        PROJECT_ROOT = sys.executable
   else:
        PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))

   pwd = os.path.dirname(PROJECT_ROOT)

   # messagebox is for the tkinter based GUI

   messagebox.showinfo('Info', 'Please wait a moment')
   subprocess.call(['python', pwd + '/Customs.py'], shell = False)
   subprocess.call(['Rscript', pwd + '/r_script.R'], shell=False)
   subprocess.call(['python', pwd + '/by_month.py'], shell = False)
   messagebox.showinfo('Info', 'Processing completed)

Мне интересно, есть ли более чистый / надежный способ сделать это, чтобы уменьшить вероятность возникновения ошибки, которая может привести к поломке программного обеспечения.

Я должен также упомянуть, что я прочитал кое-что о превращении других скриптов в исполняемый файл, и я хотел бы услышать ваше мнение по этому поводу.

Спасибо

1 Ответ

0 голосов
/ 12 июня 2019

Сначала я предлагаю вам использовать функцию, которая возвращает текущий путь к вашему файлу, когда он выполняется как замороженный скрипт или работает нормально, чтобы упростить тестирование вашего кода.

Во-вторых, если вы хотите связать свои файлы сценариев, вам нужно сначала связать свои файлы с исполняемым файлом в виде DATA-файла . Затем подготовьте путь к этому файлу при использовании их с указанной функцией.

def app_path():
    if getattr(sys, 'frozen', False):
        app_path = os.path.dirname(sys.executable)
    elif __file__:
        app_path = os.path.dirname(__file__)
    return app_path


def resource_path(relative_path):
    if hasattr(sys, '_MEIPASS'):
        return os.path.join(sys._MEIPASS, relative_path)
    return os.path.join(os.path.abspath("."), relative_path)


# messagebox is for the tkinter based GUI
messagebox.showinfo('Info', 'Please wait a moment')
subprocess.call(['python', resource_path('Customs.py')], shell=False)
subprocess.call(['Rscript', resource_path('r_script.R')], shell=False)
subprocess.call(['python', resource_path('by_month.py')], shell=False)

messagebox.showinfo('Info', 'Processing completed)

И ваша команда для создания приложения будет выглядеть примерно так:

pyinstaller -F --add-data "Customs.py;." --add-data "r_script.R;." --add-data "by_month.py;." myscript.py

Когда ваше приложение запускается, файлы данных Customs.py, r_script.R и т. Д. Будут извлечены во временную папку, а resource_path вернет точный путь для каждого файла. Но помните, что если вы хотите загрузить некоторые файлы из вашего текущего каталога (где находится исполняемый файл), вы можете использовать функцию app_path.

...