Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python“;模板";用于命令行脚本和导入模块的模块_Python_Json_Module_Argparse - Fatal编程技术网

Python“;模板";用于命令行脚本和导入模块的模块

Python“;模板";用于命令行脚本和导入模块的模块,python,json,module,argparse,Python,Json,Module,Argparse,我想编写一个python“模板”模块,以便使我的所有脚本具有相同的行为 行为如下所示: 如果脚本在命令行中运行,则它接受用argparse处理的参数。这些论点基本上是: 从stdin、文件或字符串参数中输入json 在标准输出或文件中输入一个json 如果脚本作为模块导入,则它具有管理以下情况的类/函数: 从调用对象的人那里获取输入 给输出一个对象,以便调用它的人可以使用它 我所做的: “模板”零件模板.py 由于以下建议,它在命令行中的行为完全符合我的要求: 我希望这是实现它的最

我想编写一个python“模板”模块,以便使我的所有脚本具有相同的行为

行为如下所示:

  • 如果脚本在命令行中运行,则它接受用argparse处理的参数。这些论点基本上是:
    • 从stdin、文件或字符串参数中输入
      json
    • 在标准输出或文件中输入一个
      json
  • 如果脚本作为模块导入,则它具有管理以下情况的类/函数:
    • 从调用对象的人那里获取输入
    • 给输出一个对象,以便调用它的人可以使用它
我所做的: “模板”零件模板.py 由于以下建议,它在命令行中的行为完全符合我的要求:

我希望这是实现它的最好方式

“计算面积”示例 现在,如果我使用

import template as t

def main():

    inp=t.input() # {"x":8, "y":2}

    out={'area' : inp['x'] * inp['y'] }

    return(t.output(out))

if __name__ == "__main__":
    main()
脚本在命令行中按我的要求运行:

$ echo '{"x":8, "y":2}' | ./calculate_area.py -p
{
  "area": 16
}
“calculate_sqrt”脚本将其作为一个模块进行测试 现在我需要第三个脚本将其作为模块导入

import template as t
import calculate_area as i
import numpy as np
import json

def main():

    inp=json.loads(i.main())

    out={'sqrt of area' : np.sqrt(inp['area']) }

    return(t.output(out))

if __name__ == "__main__":
    main()
问题从这里开始:

$ echo '{"x":8, "y":2}' | ./calculate_sqrt.py -p
{
  "area": 16
}
{
  "sqrt of area": 4.0
}
  • 为什么我要获得两个输入而不是最后一个
此外:

  • 如何避免在json中输入它?改为:“如果通过
    import
    调用模块,那么输入/输出将通过对象,否则将通过命令行中的
    json
我在这里保存了我的代码:
在我看来,这是一个好的基本脚本的概要:

import json,sys,argparse,os

def parser(argv=None):
    # if argv is None, uses the sys.argv[1:]
    parser = argparse.ArgumentParser(....)
    ...
    args = parser.parse_args(argv)
    return(args)

def input(args, *data):

    # if data :
    #     datain=data[0]

    if args.input_file is not None: 
        # input_file might be sys.stdin (if '-')   
        data = args.input_file.read()
    # stdin should work for < redirection
    # I don't know if works for pipe
    ...
    return(datain)

def output(args, *datain) :
    if datain :
        datain=datain[0]
    # output_file might be stdout
    ....
    return(dataout)

def main(args):
    datain = input(args, [])
    dataout = output(args, datain)
    return dataout

if __name__ == "__main__":
    args = parser()
    main(args)
另一个脚本也可以

from template import parser, input, output
def main(args):
    ... input
    # do its own thing
    ... output
# etc

模板
代码中,调用
main()
,但不处理返回的
参数
。在
input
output
中再次调用它,这一次节省了
args
。但是我没有看到对这两个函数的任何调用。
FileType
被设置为接受
-
,意思是
stdin
stdout
。这应该允许您接受重定向(甚至可能是管道?)输入/输出,而无需进行特殊测试。@hpaulj我不明白。。。我调用它是为了使用
args
values
I.main()
生成
area
字符串。它返回它,但也写入文件。如何避免它?注释掉
args.output\u file.write
将导致无输出;将
return
替换为
print
将为您的示例生成相同的行为库。它只允许运行一次解析器。但是现在,当
将模板导入为t
时,我必须调用
t.input(args,…)
t.output(args,…)
,而这并不是必需的,因为使用模板的所有脚本的参数选项都应该相同。Python中导入的模块提供了导入程序可以使用的函数和类。你的模板模型太不合适了。如果脚本需要用户的附加控件怎么办?无论如何,如果多次调用解析器,我建议去掉
FileType
s。仅在需要时自己打开和/或创建文件,最好在
环境中使用
打开和/或创建文件。
输入
功能不应创建
输出
文件。
输出
功能不应打开它不使用的
输入
文件。如果您提供了语法分析器无法识别的值,则语法分析器不应阻塞。感谢您提供的有用建议。我会更新代码
args = parser(['-i', 'inputfile.py', ....]
from template import parser, input, output
def main(args):
    ... input
    # do its own thing
    ... output
# etc