使用Argparse进行字典

时间:2017-07-28 11:58:00

标签: python dictionary argparse

我想阅读视频列表中的任何一项。视频读取和显示代码如下。这段代码工作得很好。

import cv2


def VideoReading(vid):

    cap = cv2.VideoCapture(vid)
    while True:
        ret, frame = cap.read()
        cv2.imshow('Video', frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    cap.release()
    cv2.destroyAllWindows()

由于我有大量视频,并且我通过命令行调用代码,因此编写整个视频名称非常麻烦。所以我创建了一本字典。这里给出了2的例子:

{"Video1.mp4": 1, 'Video2.mp4': 2}

现在,我使用以下代码使用值1或2调用视频,而不是使用视频名称。代码如下:

def Main():

    VideoFiles= ["Video1.mp4", "Video2.mp4"]
    VideoFilesIndicator = [1, 2]

    model_list = {}
    for i in range(len(VideoFiles)):
        model_list[VideoFiles[i]] = VideoFilesIndicator[i]

    print(model_list)
    def convertvalues(value):
        return model_list.get(value, value)

    parser = argparse.ArgumentParser()
    group = parser.add_mutually_exclusive_group()


    group.add_argument("-v", "--video", help = "add video file name of any format", type = convertvalues,\
                     choices = [1,2], default = 1)

    args =parser.parse_args()

    return VideoReading(args.video)



if __name__ == "__main__":

    Main()

现在,当我在cmd "python VideoReading.py -v 2"中运行代码时,它会向我发出以下错误。

  

错误:参数-v / - 视频:无效选择:' 2' (从1,2中选择)

我不明白为什么我会收到此错误。我正在关注this帖子来构建我的程序。

3 个答案:

答案 0 :(得分:2)

问题是convertvalues'2'作为字符串返回,因为convertvaluesvalue中找不到model_list(即字符串) {1}}。试试:

def convertvalues(value):
    return model_list.get(value, int(value))

另外,实际上,你的参数解析器总是会在video中收到一个整数(要么你传递了一个整数,要么convertvalues将一个视频文件名转换成一个整数)。要再次获取实际文件名,您可以执行类似

的操作
args = parser.parse_args()
video_file = VideoFiles[VideoFilesIndicator.index(args.video)]
return VideoReading(video_file)

我的建议是基于尝试对代码进行最少量的更改。但是,如果您对代码的最终形状感到不舒服,也可以考虑对程序进行更多更改like flevinkelming suggests

答案 1 :(得分:1)

你的词典是倒退的;您希望将数字映射到文件名,以便在输入数字时可以返回文件名。没有必要提供convertvalues的默认值,因为您使用choices来限制dict有效键的允许输入。

def main():

    video_files = ["Video1.mp4", "Video2.mp4"]

    model_list = dict(enumerate(video_files, start=1))

    print(model_list)


    parser = argparse.ArgumentParser()
    group = parser.add_mutually_exclusive_group()

    group.add_argument("-v", "--video", 
                       help="add video file name of any format",
                       type=lambda str: model_list[int(str)],
                       choices=model_list.values())

    args = parser.parse_args()

    return VideoReading(args.video)

答案 2 :(得分:1)

替代解决方案,为用户提供最少代码和动态help输出:

import argparse

def main():

    model = {
        1: "Video1.mp4",
        2: "Video2.mp4",
        3: "Video3.mp4"
    }  # Add more if needed

    videos = ['{}({})'.format(v, str(k)) for k, v in model.items()]
    help_ = "Videos to choose from: {}".format(', '.join(videos))

    parser = argparse.ArgumentParser()
    parser.add_argument('-v', '--video', help=help_, type=int, default=1)
    args = parser.parse_args()

    return VideoReading(model[args.video])

if __name__ == '__main__':
    main()

python VideoReading.py -h

usage: VideoReading.py [-h] [-v VIDEO]

optional arguments:
    -h, --help  show this help message and exit
    -v VIDEO, --v VIDEO
                      Videos to choose from: Video1.mp4(1), Video2.mp4(2),
                      Video3.mp4(3)

python VideoReading.py

如果您正在打印选择 - Video1.mp4

python VideoReading.py -v 3

如果您正在打印选择 - Video3.mp4