微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将来自 namedtuple 的信息作为 args

如何解决将来自 namedtuple 的信息作为 args

我想从与函数签名共享相同名称的命名元组中给出一个函数值,如果签名中不存在该名称,则跳过它。

import collections
row = collections.namedtuple('row',['b','a','c','d'])
row1 = row(1,2,3,4)
def assign_rows(a,b,c):
    print(a,c)
assign_rows(*row1)

返回错误

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-32-c5dc816f0d5d> in <module>
----> 1 assign_rows(*row1)

TypeError: assign_rows() takes 3 positional arguments but 4 were given

有两个问题,最明显的是上面的错误,而且我希望参数尊重namedtuple的名称,所以a=row1.a,b=row1.b,c=row1.c。有没有一种巧妙的方法来做到这一点?

解决方法

您可以将 namedtuple 作为关键字参数传递给函数,方法是将其转换为 dict 并使用双星运算符:

assign_rows(**row1._asdict())

这仍然会给您带来问题,即您在元组中有一个函数不期望的额外参数 (d),这将导致错误。

如果您不介意更改函数,请在函数签名的末尾添加 **kwargs。这将抑制错误:

def assign_rows(a,b,c,**kwargs):
    print(a,c)

如果您打算在代码的其他地方使用该函数,这不是一个干净的解决方案,因为它会抑制在某些情况下可能是有用的错误消息。在这种情况下,您可以将命名元组与函数签名进行匹配。

import inspect 

def namedtuple_to_func_args(ntuple,fn_def):
    params = inspect.signature(fn_def).parameters
    tuple_dict = ntuple._asdict()
    return {p : tuple_dict[p] for p in params.keys()}

然后使用

import collections
row = collections.namedtuple('row',['b','a','c','d'])
row1 = row(1,2,3,4)
def assign_rows(a,c):
    print(a,c)
args = namedtuple_to_func_args(row1,assign_rows)
assign_rows(**args)

在这方面还有其他旋转,它可能作为装饰器工作得更整洁,具体取决于周围的逻辑。您还应该考虑 juanpa 在关于仅使用 a=row1.a 等的评论中所说的内容,因为它简单且高效,具体取决于您使用此模式的频率以及它需要的灵活性

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?