Ответ 1
Вы ищете os.exec*()
.
У меня есть приложение GTK на основе python, которое загружает несколько модулей. Он запускается с терминала (linux) следующим образом:
./myscript.py --some-flag setting
Внутри программы пользователь может загрузить (используя Git) новые версии.
Если такое существует/загружено, появляется кнопка, которая, как мне хотелось бы, перезапустила бы программу с недавно скомпилированным содержимым (включая зависимости/импорт). Предпочтительно он также перезапускает его, используя содержимое sys.argv
, чтобы сохранить все флаги такими, какими они были.
Так что я не могу найти/нужна хорошая процедура перезапуска, которая убивает текущий экземпляр программы и запускает новый, используя те же аргументы.
Предпочтительно, решение должно работать и для Windows и Mac, но это не существенно.
Вы ищете os.exec*()
.
Я думаю, что это более сложный ответ, так как иногда у вас может быть слишком много открытых файловых объектов и дескрипторов, которые могут вызвать проблемы с памятью или параллельные подключения к сетевому устройству.
import os
import sys
import psutil
import logging
def restart_program():
"""Restarts the current program, with file objects and descriptors
cleanup
"""
try:
p = psutil.Process(os.getpid())
for handler in p.get_open_files() + p.connections():
os.close(handler.fd)
except Exception, e:
logging.error(e)
python = sys.executable
os.execl(python, python, *sys.argv)
UPDATE - из приведенного выше ответа с некоторым примером для дальнейшего использования
У меня runme.sh
#!/bin/bash
kill -9 server.py
python /home/sun/workspace/c/src/server.py &
И у меня есть server.py
, где мне нужно перезапустить само приложение, поэтому у меня было:
os.system('runme.sh')
но это не перезапустило само приложение, выполнив команду runme.sh, поэтому, когда я использовал этот способ:
os.execl('runme.sh', '')
Затем я смог перезапустить себя
Я знаю, что это решение технически не является то, о чем вы просите, но если вы хотите быть на 100% уверенным, что вы освободили все или не хотите полагаться на зависимости, вы можете просто запустить script из цикла в другой:
import os, time
while 1:
os.system("python main.py")
print "Restarting..."
time.sleep(0.2) # 200ms to CTR+C twice
Затем вы можете перезапустить main.py так же, как:
quit()
Я немного улучшил код # s3niOr.
В моем случае в пути к файлу Python есть пробелы. Таким образом, добавив правильное форматирование, проблема может быть решена.
Обратите внимание, что в моем случае мой файл python не имеет других аргументов. Так что, если у вас есть другие аргументы, вы должны разобраться с ними.
Это решает проблему перезапуска скрипта Python с пробелами в пути:
import os
import sys
import psutil
import logging
def restart_program():
"""Restarts the current program, with file objects and descriptors
cleanup
"""
try:
p = psutil.Process(os.getpid())
for handler in p.get_open_files() + p.connections():
os.close(handler.fd)
except Exception, e:
logging.error(e)
python = sys.executable
os.execl(python, python, "\"{}\"".format(sys.argv[0]))
Работает на Windows (без аргументов)
os.startfile(__file__)
sys.exit()
ИЛИ ЖЕ
os.startfile(sys.argv[0])
sys.exit()
Вдохновлен @YumYumYum и исправил проблему с помощью restart.sh и os.execl
restart.sh
#!/bin/bash/
pkill -f main.py
python main.py
Добавьте это в ваш main.py
os.excel("restart.sh","")
Я использую это, чтобы дать возможность пользователям перезапустить скрипт в консоли. Надеюсь, это поможет.
def close_restart(self,csvfile):
choice = input('Do you want to restart the program? Please select \'Y\' if you would like to restart.')
if choice == 'Y' or choice == 'y':
print('Restarting now...')
os.execl(sys.executable, sys.executable, *sys.argv)
else:
print('Thank you for using the tool!')
print('The program will close in 10s...')
time.sleep(10)
Таким образом, пользователь может ввести опцию "Y/N", чтобы перезапустить программу или нет.