【问题标题】:Python: "importing" input argumentsPython:“导入”输入参数
【发布时间】:2013-03-30 08:22:12
【问题描述】:

我有两个 python 脚本 AB,都有一个主参数和不同的输入参数(我使用 argparse)。我通常使用以下方式启动它们:

$ python A.py --paramA1 valA1 --paramA2 valA2
$ python B.py --paramB1 valB1 --paramB2 valB2

我希望能够在A 中调用B,并在启动A 时指定B 的参数。简而言之,我想用A的参数和B的参数调用A。从外面看应该是这样的:

$ python A.py --paramA1 valA1 --paramA2 valA2 --paramB1 valB1 --paramB2 valB2

有没有比将Bargparse 代码复制并粘贴到A 然后调用B 更优雅的方法?

编辑:为了简化,这里有一些示例代码:

A.py:

import argparse
def main():
    parser = argparse.ArgumentParser(description="Args for A.py")
    parser.add_argument("--param1A", type=int)
    parser.add_argument("--param2A", type=int)
    args = parser.parse_args()
    valA1 = args.param1A
    valA2 = args.param2A
    ...
    return 0

B.py:

import argparse
def main():
    parser = argparse.ArgumentParser(description="Args for B.py")
    parser.add_argument("--param1B", type=int)
    parser.add_argument("--param2B", type=int)
    args = parser.parse_args()
    valA1 = args.param1B
    valA2 = args.param2B
    ...
    return 0

包含A.pyB.py 的参数的建议C.py 到底是什么样的?那么A.pyB.py 会是什么样子呢?

编辑2:我忘了说B.py的参数之一必须在A.py中创建,所以执行顺序是@987654346 @ 然后是B,而A 必须能够将参数传递给B

【问题讨论】:

  • 我认为一个优雅的解决方案是将解析的参数包装到第三个文件中。

标签: python input arguments argparse


【解决方案1】:

您可以创建一个模块C.py,其中包含常见的argparse 逻辑并由A 和B 导入。

当从 A 调用 B 时,您还可以将已解析的参数传递给 B。我的意思是,A 和 B 都应该有类似 main 的函数,它接受已经解析的参数,因此不必进行两次解析。

C.py

import argparse

def create_parser():
    parser = argparse.ArgumentParser(description="Args for B.py")
    parser.add_argument("--param1B", type=int)
    parser.add_argument("--param2B", type=int)
    return parser

B.py

import argparse
import sys
import C

def main(args):
    valB1 = args.param1B
    valB2 = args.param2B
    # do stuff
    return 0

if __name__ == '__main__':
    parser = C.create_parser()
    args = parser.parse_args()
    sys.exit(main(args))

A.py

import argparse
import sys
import C
import B

def main(args):
    valA1 = args.param1A
    valA2 = args.param2A
    # do stuff
    return 0


if __name__ == '__main__':
    parser = C.create_parser()
    parser.add_argument("--param1A", type=int)
    parser.add_argument("--param2A", type=int)
    args = parser.parse_args()
    B.main(args)
    sys.exit(main(args))

【讨论】:

  • 谢谢。您能否根据我(现在)编辑的问题中提供的代码给我一个示例?如果我编写这个新模块 C.py,我不明白应该如何修改 A.py 和 B.py。
  • 你甚至可以完全绕过C,将create_parser放在B中,然后由A导入
  • 非常感谢!一件小事:在if __name__ == '__main__': 下写return main(args) 是否正确?我收到SyntaxError: 'return' outside function,这表明我不在该代码块中的函数内。我应该只做sys.exit(main(args))吗?
  • 啊,错过了。实际上,应该使用 sys.exit。我将编辑回复。
  • 这让事情变得完全不同。我的总体感觉是,您正在尝试使事情变得更加复杂。我宁愿遵循 Unix 哲学并尝试构建简短、简单的脚本,具有清晰的接口,然后可以通过管道和/或 xargs 将它们链接在一起。
【解决方案2】:

我认为@Ioan Alexandru Cucu 描述的内容类似于以下内容:

import argparse

class A():
    __init__(self, param1A, param2A, param1B=None, param2B=None):
        if(param1B and param2B):
            myB = B(param1B, param2B)
        #Do processing here ...
        return 0


class B():
    __init__(self, param1B, param2B):
        #Do processing here ...
        return 0

if(__name__ == '__main__'):
    parser = argparse.ArgumentParser(description="Args for A and/or B")

    parser.add_argument("--param1A", type=int)
    parser.add_argument("--param2A", type=int)

    parser.add_argument("--param1B", type=int)
    parser.add_argument("--param2B", type=int)

    args = parser.parse_args()

    if(args.param1A and args.param2A and args.param1B and args.param2B):
        A(args.param1A, args.param2A, args.param1B, args.param2B)
    if(args.param1A and args.param2A):
        A(args.param1A, args.param2A)
    elif(args.param1B and args.param2B):
        B(args.param1B, args.param2B)

您可以在多个模块中包含不同的类,而不是在一个模块中包含多个类。

【讨论】:

    猜你喜欢
    • 2016-10-16
    • 2015-06-04
    • 2012-07-12
    • 2016-05-28
    • 2016-07-27
    • 2019-05-05
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    相关资源
    最近更新 更多