【问题标题】:Dictionary: key exist or not字典:键是否存在
【发布时间】:2012-07-31 18:34:26
【问题描述】:

我使用 django 构建我的网络应用程序。其中一个页面发送不同的文件(具有不同的文件类型)。我有 6 种文件类型。而我当前的代码版本(真的很糟糕——这就是我写这个问题的原因)是:

    try:
        file = request.FILES[u'file_doc']
    except MultiValueDictKeyError:
        try:
            file = request.FILES[u'file_fb2']
        except MultiValueDictKeyError:
            try:
                file = request.FILES[u'file_pdf']
            except MultiValueDictKeyError:
                try:
                    file = request.FILES[u'file_txt']
                except MultiValueDictKeyError:
                    try:
                        file = request.FILES[u'file_other']
                    except MultiValueDictKeyError:
                        try:
                            file = request.FILES[u'file_chm']
                        except MultiValueDictKeyError:
                            return HttpResponse('bad file type')

你能告诉我 - 如何改善这种糟糕的代码和平。

TIA!

【问题讨论】:

    标签: python dictionary coding-style


    【解决方案1】:

    in 测试可让您查看某个键是否是字典的一部分。

    if u'file_doc' in request.FILES:
        file = request.FILES[u'file_doc']
    

    您可以简单地遍历一组键来测试:

    for key in (u'file_doc', u'file_fb2', .. ):
        if key in request.FILES:
            file = request.FILES[key]
            break
    else:
        return HttpResponse('bad file type')
    

    else 套件将在 for 循环完成但未到达 break 语句的情况下执行,即您没有找到匹配的键。

    请注意,您仍然可以在循环中使用您的异常方法:

    for key in (u'file_doc', u'file_fb2', .. ):
        try:
            file = request.FILES[key]
            break
        except MultiValueDictKeyError:
            pass
    else:
        return HttpResponse('bad file type')
    

    但我不确定这是否更具可读性。

    【讨论】:

    • 或者您可以在 for 循环中使用 try/except。番茄 vs 番茄 -- 或者,在 python 世界中,LBYL vs EAFP...(+1)
    • 谢谢!我第一次害怕像意大利面条一样长的 try-except 代码:)
    • @mgilson:这可能也更快(一小部分),但我发现in 测试方法看起来更容易一些。根据口味挑选! :-)
    • 如果异常情况是常见的情况(这里是),我更喜欢LBYL。另一方面,如果可以在测试文件的存在和访问文件之间删除文件,那么 EAFP 将是唯一的方法。
    【解决方案2】:

    你可以这样做:

    filetypes = [ u'file_doc', u'file_fb2', u'file_pdf' ]
    
    file = None
    for ft in filetypes:
      if ft in request.FILES:
        file = request.FILES[ft]
        break
    
    if file is None:
      return HttpResponse('bad file type')
    

    【讨论】:

    • 当您找到正确的文件类型时,您不想 break 退出该 for 循环吗?
    • 如果所有三个文件名都存在,您将得到最后一个匹配项。
    • 非常感谢!这真的是python方式的解决方案:)
    • @Sam:是的!我最初在那里有回报,但意识到这不符合 OP 做事的方式。固定!
    【解决方案3】:

    request.FILES.get(u'file_doc', DEFAULT_VALUE) 将返回 DEFAULT_VALUE 如果该键在字典中不存在。您还可以使用 Martijn 提到的 in 关键字 编辑另见django MultiValueDictKeyError error, how do i deal with it

    【讨论】:

      【解决方案4】:
      def GetFile(request):
          file_types = "doc fb2 pdf txt other chm".split()
          for k in file_types:
              if "file_{0}".format(k) in request.FILES:
                   return request.FILES["file_{0}".format(k)]
      

      至少我会这样做

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多