繁体   English   中英

如果我用“ python -m”运行它,如何重新启动我的Python脚本?

[英]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文件,通过使用-mopencryptobot告诉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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM