python + argparse - 如何从命令行获取可选参数的顺序

Ska*_*ach 5 python argparse

我想知道如何获取从命令行传递给 argparse 的可选参数的顺序

我有图像处理类,它能够对图像应用不同的操作 - 如旋转、裁剪、调整大小......

应用这些操作的顺序通常是必不可少的(例如:您想在调整图像大小之前对其进行裁剪)

我有这个代码:

parser = argparse.ArgumentParser(description='Image processing arguments')

parser.add_argument('source_file', help='source file')
parser.add_argument('target_file', help='target file')

parser.add_argument('-resize', nargs=2, help='resize image', metavar=('WIDTH', 'HEIGHT'))
parser.add_argument('-rotate', nargs=1, help='rotate image', metavar='ANGLE')
parser.add_argument('-crop', nargs=4, help='crop image', metavar=('START_X','START_Y','WIDTH','HEIGHT'))

ar = parser.parse_args()

print ar
Run Code Online (Sandbox Code Playgroud)

但是 - 无论我以何种顺序将参数传递给脚本:

cmd.py test.jpg test2.jpg -crop 10 10 200 200 -resize 450 300

cmd.py test.jpg test2.jpg -resize 450 300 -crop 10 10 200 200

在命名空间中的项目总是按相同的顺序排列(我想是按字母顺序排列的):

Namespace(crop=['10', '10', '200', '200'], resize=['450', '300'], rotate=None, source_file='test.jpg', target_file='test
2.jpg')
Run Code Online (Sandbox Code Playgroud)

有没有办法按命令行字符串中的位置对它们进行排序或获取它们的索引?

imm*_*tal 5

您总是可以查看sys.argv哪个是列表(并因此排序)并简单地迭代它以检查哪个参数先出现或使用list.index()来查看您的关键字在列表中的相应位置...

sys.argv包含在命令行中输入的单词列表(除非字符串被引号包围,否则此类“单词”的分隔符是空格)。这意味着如果用户输入类似./my_proggie -resize 500then 的内容sys.argv将包含如下列表:['./my_proggie', '-resize', '500']


hpa*_*ulj 5

命名空间是一个简单的对象,它str()根据其 .txt 文件中键的顺序列出其属性__dict__。属性设置为setattr(namespace, dest, value).

一种解决方案是定义自定义命名空间类。例如:

class OrderNamespace(argparse.Namespace):
    def __init__(self, **kwargs):
        self.__dict__['order'] = []
        super(OrderNamespace, self).__init__(**kwargs)
    def __setattr__(self,attr,value):
        self.__dict__['order'].append(attr)
        super(OrderNamespace, self).__setattr__(attr, value)
Run Code Online (Sandbox Code Playgroud)

并使用

args = parser.parse_args(None, OrderNamespace())
Run Code Online (Sandbox Code Playgroud)

为你的两个例子制作

OrderNamespace(crop=..., order=[..., 'crop', 'resize'], resize=...)
OrderNamespace(crop=..., order=[..., 'resize', 'crop'], resize=...)
Run Code Online (Sandbox Code Playgroud)

order属性给出了设置其他属性的顺序。初始项目用于默认值和文件位置。添加default=argparse.SUPPRESS到参数将抑制其中一些项目。这个自定义类可以更复杂,例如使用 OrderedDictionary,仅记录所选参数的顺序,或用于order控制属性的显示。

另一种选择是使用创建此order属性的自定义 Action 类,例如

class OrderAction(argparse._StoreAction):
    def __call__(self, parser, namespace, values, option_string=None):
        setattr(namespace, self.dest, values)
        order = getattr(namespace, 'order') if hasattr(namespace, 'order') else []
        order.append(self.dest)
        setattr(namespace, 'order', order)
Run Code Online (Sandbox Code Playgroud)