【问题标题】:How do i write this code more pythonic way我如何以更 Python 的方式编写此代码
【发布时间】:2020-03-25 06:52:40
【问题描述】:

我正在编写 Django 的视图来检查是否提供了有效的专辑 ID。但它看起来很麻烦且难以阅读。我想让它更具可读性和简短性。我不能直接检查data['id']。空白会报错。

def post(self, request):
    if len(request.body) > 0:
        data = json.loads(request.body.decode('utf-8'))
    else:
        return Response({'message': 'Album id is required'})

    if 'id' not in data:
        return Response({'message': 'Valid Album id is required'})

    try:
        id = int(data['id'])
        if id < 1:
            return Response({'message': 'Valid album id is required'})
        album = Album.objects.get(pk=id)
    except:
        return Response({'message': 'Valid album id is required'})

【问题讨论】:

  • 这段代码有一个与风格无关的明显问题:裸露的try: ... except: ... 您实际上期望会遇到什么错误?您应该始终尽可能地捕获具体的错误。至于pythonic:if len(request.body) &gt; 0:应该只是if request.body:
  • 为了可读性,第一行使用函数来封装逻辑
  • 是的。我还有其他类似的看法。所以我将使用函数使其更具可读性。
  • 您可以将特定错误添加到您的 except

标签: python django python-3.x django-rest-framework


【解决方案1】:

整个问题似乎是当id 不是data 中的有效条目时该怎么办。

查看您的代码,尤其是下面的部分,似乎小于 1 的 id 值无效。

 if id < 1:
    return Response({'message': 'Valid album id is required'})

此外,try...except 意味着,如果id 不是data 的一部分,那么这也是无效的。

这意味着您的代码可以通过使用默认值来简化,例如:

def post(self, request):
    if len(request.body) > 0:
        data = json.loads(request.body.decode('utf-8'))
    else:
        return Response({'message': 'Album id is required'})

    id = int(data.get('id', 0))
    if id < 1:
        return Response({'message': 'Valid album id is required'})
    album = Album.objects.get(pk=id)
    # f-strings below are a python 3
    return Response({'message': f'The album you have requested is {album}'})

上面sn-p的重要部分是:data.get('id', 0) 如果id 是有效字段,则返回data['id'],如果在data 中找不到id,则返回0

不相关,因为两者都是检查request.body的有效方法,但更pythonic的方法是像@juanpa.arrivillaga建议的那样做,即: if request.body:

为了进一步简化,我会通过这种方式减少一些重复:

def post(self, request):
    if request.body:
        data = json.loads(request.body.decode('utf-8'))

        id = int(data.get('id', 0))
        if id < 1:
            return Response({'message': 'Valid album id is required'})
        album = Album.objects.get(pk=id)
        # f-strings below are a python 3
        return Response({'message': f'The album you have requested is {album}'})

    return Response({'message': 'Album id is required'})

【讨论】:

    【解决方案2】:

    在尝试提高可读性时要牢记的最重要的两件事是不要过早地优化使用函数来封装逻辑(尤其是如果该逻辑可能必须将来可以重复使用)。

    所以,只是一个简单的例子:

    def post(self, request):
        if request.body:
            data = json.loads(request.body.decode('utf-8'))
        else:
            return Response({'message': 'Album id is required'})
    
        if _validate_data(data):
            id_ = int(data['id'])
            album = Album.objects.get(pk=id_)
            # probably want to return a Response as well...
        else:
            return Response({'message': 'Valid Album id is required'})
    
    
    def _validate_data(data):
        if 'id' not in data:
            return False
        try:
            id_ = int(data['id'])
        except ValueError:
            return False
        return id_ >= 1
    

    您可以采取不同的方法。例如,当data 无效时,您可以使用_extract_id 而不是_validate_data,它返回None,否则您可以检查id_,例如:

    id_ = _extract_id(data)
    if id_ is None:
        return Response({'message': 'Valid Album id is required'})
    else:
        # do the rest of the stuff
    

    鉴于您的其余代码和您遵循的任何标准,您必须决定什么更有意义。

    顺便说一句,这对我来说似乎不是一个帖子,因为看起来你只是在检索数据,按 id 的专辑,POST 通常用于创建新资源。

    【讨论】:

      猜你喜欢
      • 2023-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-07
      • 1970-01-01
      • 2016-10-13
      • 2011-11-19
      • 1970-01-01
      相关资源
      最近更新 更多