使参数无效以创建NamedTuple实例

时间:2018-12-25 13:22:21

标签: python python-3.x

我想为创建名称的操作定义个人文本

from typing import NamedTuple

class User(NamedTuple):
    email: str
    username: str

和make用户函数的两种解决方案,第一种具有少量代码,但是错误文本对于人类而言不够可读

def make_user(params: dict):
    try:
        user = User(**params)
    except TypeError as e:
        return None, e
    return user, None

结果如下:

params = {'email': '1@1.test'} 
make_user(params)

(None,
TypeError("__new__() missing 1 required positional argument: 'username'"))

另一种解决方案是在实例初始化之前手动检查字段:

def make_user_or_error(params: dict):
    user_required = User._fields ^ User._field_defaults.keys()
    required = [x for x in user_required if x not in params]
    if required:
        return None, f'You should provide values for the field(s): {",".join(required)}'
    return User(**params), None

结果是:

params = {'email': '1@1.test'} 
make_user_or_error(params)
(None, 'You should provide values for the field(s): username')

问题是:是否确实存在像第一个那样用最少的代码但在第二个中却得到了结果的解决方案

1 个答案:

答案 0 :(得分:1)

通过从错误字符串中获取缺少字段的名称并自己构建错误消息,可以采用中间解决方案。

我提出的解决方案非常幼稚,可以处理一个遗漏的论点,我相信您将能够对此进行概括。

from typing import NamedTuple
import re

missing_field_regex = re.compile(r"argument: '(.*)'")

class User(NamedTuple):
    email: str
    username: str


def make_user(params: dict):
    try:
        user = User(**params)
    except TypeError as e:
        return None, f'You should provide values for the field(s): {missing_field_regex.findall(str(e))[0]}'
    return user, None

params = {'email': '1@1.test'}
print(make_user(params))
# (None, 'You should provide values for the field(s): username')