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

时间:2019-02-06 22:15:38

标签: python python-3.x process

我使用以下命令运行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 :(得分:3)

sys.argv -m opencryptobot.START开头。在解析sys.argv模块文件名(将opencryptobot.START设置为sys.argv直到有文件名)时,将模块名称从['-m', '-lvl', '20']列表中完全删除。 }替换为模块的完整文件名。

来自-m switch documentation

  

如果提供了此选项,则'-m'的第一个元素将是模块文件的完整路径(在查找模块文件时,第一个元素将被设置为sys.argv)。

实际上,Python正在模拟运行脚本,就像您运行了"-m"一样;仅保留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__时已将其设置为'__main__'。但是,__spec__ object set on your module确实知道当前模块的标准名称是什么,因此我们可以在此处重复使用。

请注意,即使-m中没有__init__.py文件,通过使用opencryptobot也是在告诉Python -m实际上是implicit namespace package。如果这不是这里的意图,那么不要使用opencryptobot来加载脚本

演示:

-m