[英]How to restart my Python script if I run it with “python -m”?
我使用以下命令运行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
了各种版本的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
。
sys.argv
不能以-m opencryptobot.START
开头。 解析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 ...
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__
对象确实知道当前模块的全限定名,因此我们可以在此处重复使用该名称。
请注意,即使opencryptobot
没有__init__.py
文件,通过使用-m
您opencryptobot
告诉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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.