我的包具有以下结构:
mypackage
|-__main__.py
|-__init__.py
|-model
|-__init__.py
|-modelfile.py
|-simulation
|-sim1.py
|-sim2.py
文件__main__.py
的内容是
from mypackage.simulation import sim1
if __name__ == '__main__':
sim1
因此,当我执行python -m mypackage
时,脚本sim1.py
运行。
现在我想向命令行添加一个参数,以便python -m mypackage sim1
运行sim1.py
和python -m mypackage sim2
运行sim2.py
我试过以下方法:
import sys
from mypackage.simulation import sim1,sim2
if __name__ == '__main__':
for arg in sys.argv:
arg
但它运行两个脚本,而不是传入参数的脚本
在{
from mypackage.model import modelfile
print('modelfile.ModelClass.someattr')
您只需使用模块名作为参数调用
__import__
,例如:在你的循环中
例如,您的主程序名为
example.py
:请注意
sys.argv[0]
包含程序名你有你的
sim1.py
:和你的
sim2.py
:然后你可以打电话
输出:
你的代码没有达到你想要的效果。只是
sim1
实际上并没有调用函数;这样做的语法是sim1()
您可以使Python脚本将命令行中的随机字符串作为Python表达式进行计算,但这并不是解决此问题的安全或优雅的方法。相反,将字符串映射到内部函数,这些函数可能具有相同的名称,也可能不具有相同的名称。比如说,
如图所示,您在命令行上接受的符号不需要与要运行的函数的名称相对应。如果您希望成为这种情况,您可以将其简化为使用字典:
这里可能需要注意的是,您可以从命令行中准确地选择要让用户访问的Python符号,并且不允许其他符号泄漏。这将是一个安全问题(想想如果有人传入
'import shutil; shutil.rmtree("/")'
作为要运行的参数会发生什么)。这在精神上类似于避免eval
的许多理由,你会发现谷歌很容易找到这些理由(如果你不熟悉的话,你可能应该这样做)如果
sim1
是一个模块名,您只想在用户明确请求时导入它,这也不难做到;请参见importing a module when the module name is in a variable,但是您不能在脚本的前面部分import
使用它但是一般来说,模块应该只定义函数,并让调用者在调用模块之后的某个时间决定是否以及何时运行它们
也许可以从另一个角度来研究像
click
这样的第三方库,它很容易让您将所选函数作为Python脚本的“子命令”公开,这与git
的子命令init
、log
等类似假设您有包含以下内容的文件
sim1.py
main.py
output
当您将
sim1
导入main.py
并调用其函数simulation1
时,This is simulation 1
将被打印两次。 因为,simulation1
在sim1.py
内调用,也在main.py
内调用如果希望在
sim1.py
中运行该函数,但不希望在导入sim1
时运行,则可以将其放置在if __name__ == "__main__":
中sim1.py
main.py
output
相关问题 更多 >
编程相关推荐