我有多个需要由主脚本包装的脚本。每个脚本都包含在该脚本中使用的包含输入参数的函数。
例如,foo.py:
import argparse
import sys
import os
parser = argparse.ArgumentParser()
parser.add_argument("foo_input_dir")
parser.add_argument("foo_ouput_dir")
args = parser.parse_args()
def foo(input_file):
print input_file
print args.foo_input_dir
print args.foo_ouput_dir
并且主脚本应该输入带有文件和文件列表的目录,bar.py:
import argparse
import foo
parser = argparse.ArgumentParser()
parser.add_argument("main_input")
parser.add_argument("input_dir")
parser.add_argument("ouptut_dir")
args = parser.parse_args()
def bar():
print args
foo.foo(main_input)
bar()
但是,当我尝试在命令行中运行它时,出现以下错误:
使用3个参数,bar.py
需要python bar.py示例/ usr / / bin /
用法:bar.py [-h] foo_input_dir foo_ouput_dir
bar.py:错误:无法识别的参数:/ bin /
有2个参数,
python bar.py / usr / / bin /
用法:bar.py [-h] main_input input_dir ouptut_dir
bar.py:错误:参数太少
我正在尝试foo()
使用bar.py
作为args.foo_input_dir
和args.foo_output_dir
的输入。
我该如何处理这个问题?
答案 0 :(得分:0)
这不是全局变量的问题。发生的事情是两个解析器都在命令行sys.argv
上运行。
当您运行bar.py
时,它会导入foo
。作为导入的一部分,它创建解析器并执行parse_args
,期望2个字符串。如果它变为3,则会引发错误并退出。
但是现在main
创建了自己的解析器并运行它。如果它只看到foo
接受的2,它需要3个字符串和对象。
关键是两个解析器都使用相同的sys.argv
。
两个错误中的usage
行清楚地表明哪个解析器正在反对。
通常,在同一代码中运行两个独立的解析器并不是一个好主意。你可以使它工作,但它需要更多的协调而不是它的价值。当人们尝试将自己的参数添加到由Google youtube API等导入包定义的API时,有几个SO问题。
通常我们将解析器放在if __name__
块(或至少它的parser.parse_args
调用)中的可导入模块中。这样它只在用作脚本时使用。导入时不使用它。
这两个文件一起工作
foo.py:
import argparse
def make_parser():
parser = argparse.ArgumentParser()
parser.add_argument("foo_input_dir")
parser.add_argument("foo_ouput_dir")
return parser
def foo(input_file):
print input_file
print 'foo', args
if __name__ == '__main__':
parser = make_parser()
args = parser.parse_args()
foo('test')
bar.py
import argparse
import foo
def bar():
print 'bar', args
foo.foo(args.main_input)
parser = argparse.ArgumentParser()
parser.add_argument("main_input")
parser.add_argument("input_dir")
parser.add_argument("ouptut_dir")
if __name__ == '__main__':
args = parser.parse_args()
foo.args = args # make args visible to foo.foo
bar()
1827:~/mypy/stack41947308$ python foo.py a b
test
foo Namespace(foo_input_dir='a', foo_ouput_dir='b')
1828:~/mypy/stack41947308$ python bar.py a b c
bar Namespace(input_dir='b', main_input='a', ouptut_dir='c')
a
foo Namespace(input_dir='b', main_input='a', ouptut_dir='c')
在bar.args
中显示foo
变量需要特殊步骤。
属性名称不同。
作为一般规则,在可能导入的函数中使用全局变量不是一个好主意。可以使用保证在其自己的模块中定义的全局变量(模块常量),但不要依赖于将由导入器设置的全局变量。将所有变量作为参数传递更安全。