将初始化参数传递给超类的最佳实践?

时间:2016-05-04 00:14:39

标签: python-3.x initialization argparse super

我正在试图找出在Python3中初始化子/超类的最佳方法。基类和子类都将占用六个参数,所有这些参数都将从命令行参数中解析。

实现这一点的显而易见的方法是一次解析所有的args,并将它们全部传递出去:

class Base:
  def __init__(self, base_arg1, base_arg2, base_arg3):

class Sub(Base):
  def __init__(self, sub_arg1, sub_arg2, sub_arg3,
                     base_arg1, base_arg2, base_arg3):
    super().__init__(self, base_arg1, base_arg2, base_arg3)

main():
    # parse args here
    options = parser.parse_args()

    obj = Sub(options.sub_arg1, options.sub_arg2, options.sub_arg3,
              options.base_arg1, options.base_arg2, options.base_arg3)

如果我有一个Sub-subclass(我会),就通过连续的super()。 init ()调用传递的参数列表而言,事情变得非常毛茸茸。

但是我发现argparse.parse_known_args()提供了另一条路径:我可以让每个子类解析出它需要/识别的参数,并将其余的参数传递给层次结构:

class Base:
    def __init__(self, args):
        base_options = base_parser.parse_known_args(args)

class Sub(Base):
    def __init__(self, args):
        (sub_options, other_args) = sub_parser.parse_known_args(args)
        super().__init__(self, other_args)

main():
    obj = Sub(sys.argv)

从API的角度来看,这似乎更清晰。但是我可以想象它违反了“Python中已经完成的事情”的一些原则,并且出于各种原因这是一个坏主意。我对网络的搜索没有任何一个例子 - Stack Overflow的强大和全知的想法能帮助我理解正确的方法吗?

2 个答案:

答案 0 :(得分:0)

查看argparse.py代码。 ArgumentParser_ActionsContainer的子类。所有actions都是Action的子类。

致电时

parser.add_argument('foo', action='store_action', ...)

将参数传递给*args**kwargs_StoreAction,然后将它们传递给supper(在设置一些默认值之后等)

作为一个意味着要导入的模块,并且永远不会作为脚本运行,它没有if __name__....块。但通常我会包含这样一个块来调用测试代码。这是放置命令行解析器的地方,或者至少是调用它的地方。如果可能在正文中的函数中定义,但通常在导入模块时不应调用它。

一般来说,argparse是一个脚本工具,不应该成为类定义的一部分 - 除非您是一个子类ArgumentParser来添加一些新功能。

您可能还想查看https://pypi.python.org/pypi/plac。这个包为argparse提供了一个不同的接口,是子解析这个解析器的一个很好的例子。

答案 1 :(得分:0)

谢谢你!我认为你的回答帮助我弄清楚了一个更简单的方法。我可以解析顶层的所有选项,然后只传递选项命名空间,让每个子类拉出它需要的那些。与其他方法相比,面部手掌简单:

class Base:
    def __init__(self, options):
        base_arg1 = options.base_arg1
        base_arg2 = options.base_arg2

class Sub(Base):
    def __init__(self, options):
        super().__init__(self, options) # initialize base class
        sub_arg1 = options.sub_arg1
        sub_arg2 = options.sub_arg2

main():
    options = parser.parse_args()
    obj = Sub(options)