在维护 "python -c exectfile" 界面的同时更新 Python CLI
Updating Python CLI while maintaining "python -c exectfile" interface
我有许多脚本通过以下方式引用 Python 程序:
python -c "execfile('myfile.py'); readFunc(param='myParam', input='blahblah')"
界面。我想做的事情在概念上很简单:使用 "main" 和普通的 Python CLI 界面开发一个更加模块化的系统,然后调用这些函数,同时维护现有界面,因此构建脚本使用它仍然有效。
这可能吗?
理想情况下,如果我要打电话给
python myFile readFunc myParam blabblah
它会是这样的:
main(sys.argv):
readFunc(sys.argv[2], sys.arg[3])
我试过类似的方法,但效果不佳。是否可以保留两个 interfaces/methods 调用?
谢谢!
第一个想到的想法源于 execfile()
函数的可选参数。您也许可以这样做:
#!python
def main(args):
results = do_stuff()
return results
if __name__ == '__main__':
import sys
main(sys.argv[1:])
if __name__ == 'execfile':
main(args)
... 然后当你想通过 execfile()
调用它时,你为其可选的 globals
参数提供一个字典:
#!sh
python -c 'execfile(myfile, {"__name__":"execfile", "args":(1,2,3)}); ...'
当您通过 -c
调用您的功能时,这确实需要一些额外的工作,因为您必须记住传递该字典并覆盖 '__name__'
......我想你实际上可以使用 any 有效的 Python 标识符。只是 __name__
最接近您的实际操作。
下一个想法感觉有点 脏 但依赖于 __file__
全局标识符的明显处理。调用 python -c
时似乎未设置,如果正在导入或执行文件则设置。所以这有效(至少对于 CPython 2.7.9):
#!/usr/bin/env python
foo='foo'
if __name__ == '__main__' and '__file__' not in globals():
print "Under -c:", foo
elif __name__ == '__main__':
print "Executed standalone:", foo
... 如果您使用它,请不要相信我。看起来...
……嗯……
...只是...
..... 错误
如果我理解这个
python myFile readFunc myParam blabblah
正确的,你想将argv[1]
解析为要执行的命令名。
那就这样吧
if __name__ == '__main__':
import sys
if len(sys.argv) < 2 or sys.argv[1].lower() == 'nop' or sys.argv[0] == '-c': # old, legacy interface
pass
elif sys.argv[1].lower() == 'readfunc': # new one
readFunc(sys.argv[2:])
第二部分在直接执行文件时执行(通过 python file.py readFunc myParam blabblah
或通过 python -m file readFunc myParam blabblah
)
"nop" / empty argv
分支在使用 "legacy" 界面时开始发挥作用:在这种情况下,您很可能没有给出命令行参数,因此可以假设您不想执行任何事情。
这使得情况和以前一样:readFunc
标识符被导出并且可以像以前一样从 -c
脚本中使用。
我有许多脚本通过以下方式引用 Python 程序:
python -c "execfile('myfile.py'); readFunc(param='myParam', input='blahblah')"
界面。我想做的事情在概念上很简单:使用 "main" 和普通的 Python CLI 界面开发一个更加模块化的系统,然后调用这些函数,同时维护现有界面,因此构建脚本使用它仍然有效。
这可能吗?
理想情况下,如果我要打电话给
python myFile readFunc myParam blabblah
它会是这样的:
main(sys.argv):
readFunc(sys.argv[2], sys.arg[3])
我试过类似的方法,但效果不佳。是否可以保留两个 interfaces/methods 调用?
谢谢!
第一个想到的想法源于 execfile()
函数的可选参数。您也许可以这样做:
#!python
def main(args):
results = do_stuff()
return results
if __name__ == '__main__':
import sys
main(sys.argv[1:])
if __name__ == 'execfile':
main(args)
... 然后当你想通过 execfile()
调用它时,你为其可选的 globals
参数提供一个字典:
#!sh
python -c 'execfile(myfile, {"__name__":"execfile", "args":(1,2,3)}); ...'
当您通过 -c
调用您的功能时,这确实需要一些额外的工作,因为您必须记住传递该字典并覆盖 '__name__'
......我想你实际上可以使用 any 有效的 Python 标识符。只是 __name__
最接近您的实际操作。
下一个想法感觉有点 脏 但依赖于 __file__
全局标识符的明显处理。调用 python -c
时似乎未设置,如果正在导入或执行文件则设置。所以这有效(至少对于 CPython 2.7.9):
#!/usr/bin/env python
foo='foo'
if __name__ == '__main__' and '__file__' not in globals():
print "Under -c:", foo
elif __name__ == '__main__':
print "Executed standalone:", foo
... 如果您使用它,请不要相信我。看起来...
……嗯……
...只是...
..... 错误
如果我理解这个
python myFile readFunc myParam blabblah
正确的,你想将argv[1]
解析为要执行的命令名。
那就这样吧
if __name__ == '__main__':
import sys
if len(sys.argv) < 2 or sys.argv[1].lower() == 'nop' or sys.argv[0] == '-c': # old, legacy interface
pass
elif sys.argv[1].lower() == 'readfunc': # new one
readFunc(sys.argv[2:])
第二部分在直接执行文件时执行(通过 python file.py readFunc myParam blabblah
或通过 python -m file readFunc myParam blabblah
)
"nop" / empty argv
分支在使用 "legacy" 界面时开始发挥作用:在这种情况下,您很可能没有给出命令行参数,因此可以假设您不想执行任何事情。
这使得情况和以前一样:readFunc
标识符被导出并且可以像以前一样从 -c
脚本中使用。