将函数的 return 类型从字典转换为命名元组的装饰器
Decorator to transform the return type of a function from a dictionary to a namedtuple
我写了一个 hack gist 来装饰一个 return 是字典的函数,以便将 dict 转换为 namedtuple。它有很多弱点,我想从 python 专家那里知道是否有其他方法可以得到更强大的版本
弱点:
- 使用
inspect.getsource
检索包含 return 的行。它仅适用于最后一个 return 语句。
- 对某些人可以编写描述字典的语句的所有方式进行硬编码。也许我遗漏了一些极端情况。
namedtuple
的名称是硬编码的
如果您延迟创建 namedtuple
(等到第一次调用),您可以完全避免使用 inspect
。您还可以选择将 namedtuple class 的名称作为装饰器参数的一部分传递。
def namedtuplefy(func, name=None):
nt = None
@wraps(func)
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
nonlocal nt
if nt is None:
nt = namedtuple(name or (func.__name__ + '_nt'), res.keys())
return nt(**res)
return wrapper
即使在包装函数只是从另一个函数冒泡出一个字典,从一些可迭代的理解中形成一个字典等情况下,这现在也可以工作。
没有nonlocal
:
def namedtuplefy(func, name=None):
@wraps(func)
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
if wrapper.nt is None:
wrapper.nt = namedtuple(name or (func.__name__ + '_nt'), res.keys())
return wrapper.nt(**res)
wrapper.nt = None
return wrapper
我写了一个 hack gist 来装饰一个 return 是字典的函数,以便将 dict 转换为 namedtuple。它有很多弱点,我想从 python 专家那里知道是否有其他方法可以得到更强大的版本
弱点:
- 使用
inspect.getsource
检索包含 return 的行。它仅适用于最后一个 return 语句。 - 对某些人可以编写描述字典的语句的所有方式进行硬编码。也许我遗漏了一些极端情况。
namedtuple
的名称是硬编码的
如果您延迟创建 namedtuple
(等到第一次调用),您可以完全避免使用 inspect
。您还可以选择将 namedtuple class 的名称作为装饰器参数的一部分传递。
def namedtuplefy(func, name=None):
nt = None
@wraps(func)
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
nonlocal nt
if nt is None:
nt = namedtuple(name or (func.__name__ + '_nt'), res.keys())
return nt(**res)
return wrapper
即使在包装函数只是从另一个函数冒泡出一个字典,从一些可迭代的理解中形成一个字典等情况下,这现在也可以工作。
没有nonlocal
:
def namedtuplefy(func, name=None):
@wraps(func)
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
if wrapper.nt is None:
wrapper.nt = namedtuple(name or (func.__name__ + '_nt'), res.keys())
return wrapper.nt(**res)
wrapper.nt = None
return wrapper