Как перезапустить мой скрипт Python, если я запускаю его с "python -m"? - PullRequest
0 голосов
/ 07 февраля 2019

Я запускаю свой скрипт на Python с

python3.7 -m opencryptobot.START -lvl 20

opencryptobot - это папка здесь, а START - это модуль.В какой-то момент я хотел бы перезапустить скрипт с этим кодом:

os.execl(sys.executable, sys.executable, *sys.argv)

Я использую этот код, потому что он отлично работал для других моих скриптов, которые я не выполняю с аргументом -m.Поэтому приведенный выше код будет выполнен в какой-то момент, и тогда я получу эту ошибку:

ModuleNotFoundError: No module named 'opencryptobot'

Звучит правильно, поскольку opencryptobot - это просто папка, а не модуль.Я поиграл с различными версиями os.exec, чтобы посмотреть, смогу ли я его перезапустить, но на самом деле ничего не работает.

Так что мой вопрос, как я могу перезапустить мой скрипт, если я запускаю его так, как я делаю??

Это минимальная версия структуры моей папки:

.
├── LICENSE
├── Pipfile
├── Pipfile.lock
├── README.md
├── opencryptobot
│   ├── START.py
│   ├── config.py
│   ├── constants.py
│   ├── database.py
│   ├── emoji.py
│   ├── plugin.py
│   ├── plugins
│   │   ├── about.py
│   │   ├── admin.py
│   │   └── alltimehigh.py
│   ├── ratelimit.py
│   ├── telegrambot.py
│   └── utils.py
└── start.sh

Я выполняю START из корневой папки.

1 Ответ

0 голосов
/ 07 февраля 2019

sys.argv не не начинается с -m opencryptobot.START.Имя модуля полностью удаляется из списка sys.argv при разрешении имени файла модуля opencryptobot.START (sys.argv устанавливается на ['-m', '-lvl', '20'] до тех пор, пока не будет найдено имя файла), а затем '-m' заменяется полным именем файла модуля.

Из документации по ключу -m :

Если задана эта опция, первым элементом sys.argv будет полный путь кфайл модуля (в то время как файл модуля находится, первый элемент будет установлен на "-m").

По сути, Python симулирует запуск скрипта, как если бы вы запустили python /path/to/opencrytobot/START.py ...;сохраняется только контекст __package__, поэтому вы все равно можете использовать относительный к пакету импорт, такой как from . import ....

Так, чтобы воссоздать исходную командную строку, используйте '-m', __spec__.name, *sys.argv[1:] в качествесписок аргументов за пределами sys.executable:

os.execl(sys.executable, sys.executable, '-m', __spec__.name, *sys.argv[1:])

К сожалению, вы не можете использовать __name__, так как при использовании -m было установлено значение '__main__'.Однако объект __spec__, установленный на вашем модуле , знает, какое полное имя указано для текущего модуля, поэтому мы можем использовать его здесь снова.

Обратите внимание, что даже при наличииэто не __init__.py файл в opencryptobot, используя -m, вы говорите Python, что opencryptobot - это действительно неявный пакет пространства имен .Если это не было целью, то не используйте -m для загрузки скрипта .

Демо:

$ ls -1 opencryptobot/
START.py
$ cat opencryptobot/START.py
import sys
import os

if __name__ == '__main__':
    print('Running as the __main__ script')
    print('sys.argv:', sys.argv)
    print('__spec__.name:', __spec__.name)

    if 'restarted' not in sys.argv:
        print('Respawning:')
        # add an extra command-line option to stop respawning a second time
        os.execl(sys.executable, sys.executable, '-m', __spec__.name, *sys.argv[1:], 'restarted')
$ python3.7 -m opencryptobot.START -lvl 20
Running as the __main__ script
sys.argv: ['/.../opencryptobot/START.py', '-lvl', '20']
__spec__.name: opencryptobot.START
Respawning:
Running as the __main__ script
sys.argv: ['/.../opencryptobot/START.py', '-lvl', '20', 'restarted']
__spec__.name: opencryptobot.START
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...