创建于
2024-01-30 23:42
保质期
新鲜度
0%
对于已事先声明的参数——即不通过 args 或 kwargs 传递的参数,Python 无法检测到是否被省略,因为无法分辨入参来源于调用还是默认值。
以下示例封装了一个用于构造自定义标准响应的函数,标准响应约定为必定带有三个字段的JSON对象,其中 code 字段必定为整数,message 必定为字符串,data 可以为任意值。
from typing import Any
from django.db.models import IntegerChoices
class ErrorCode(IntegerChoices):
"""
自定义错误代码。
"""
SUCCESS = 1, 'success.'
DONE = 0, 'done.'
FAIL = -1, 'fail, see message.'
def response(data: Any = None,
code: ErrorCode = ErrorCode.FAIL,
message: str = None,
**kwargs):
"""
构造项目自定义的 RESTful API 标准响应内容。
"""
return {
'code': code.value,
'message': message or code.label,
'data': data,
**kwargs,
}
body = response(message=None)完成 response() 的抽象后,返回的 message 不会为 None,而参数 message 的默认值又为 None,导致前后矛盾,调用者往往需要参阅源码了解编写场景,继而造成抽象泄漏。
笔者认为比较好的做法是将参数 message 的默认值改为不常用的字面值 ...,这样在阅读函数的文档时,调用者不再会认为 message 允许为 None,与标准响应不允许 message 为 null 的约定一致。
但需要注意的是,None 的布尔值对应为 False,... 的布尔值对应为 True,改换默认值之后 or 之类的逻辑表达式需要同步变换。
from typing import Any
from django.db.models import IntegerChoices
class ErrorCode(IntegerChoices):
"""
自定义错误代码。
"""
SUCCESS = 1, 'success.'
DONE = 0, 'done.'
FAIL = -1, 'fail, see message.'
def response(data: Any = None,
code: ErrorCode = ErrorCode.FAIL,
message: str = ...,
**kwargs):
"""
构造项目自定义的 RESTful API 标准响应内容。
"""
msg = None if message is ... else message
return {
'code': code.value,
'message': msg or code.label,
'data': data,
**kwargs,
}
body = response(message=None)