【问题标题】:Optionally passing an extra dictionary to a method / function可选地将额外的字典传递给方法/函数
【发布时间】:2021-11-09 17:13:04
【问题描述】:

我正在编写如下函数:

def create_objection(name, position, **kwargs):
    dicct = {'name':name,
             'position':position}
    print(len(kwargs))
    dicct.update({'extra_info': kwargs})
    return dicct

这个函数应该总是获取名称和位置,并最终获取 for 或字典中的键/值对集合。 我想要的是以下工作方式:

create_objection('c1',{'t':1})

输出:

 0
 {'name': 'c1', 'position': {'t': 1}, 'extra_info': {}}

当我尝试这个时,我得到一个错误:

create_objection('c1',{'t':1},{'whatever':[3453,3453]},{'whatever2':[34,34]})

错误:

TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_32291/2973311999.py in <module>
----> 1 create_objection('c1',{'t':1},{'tt':2,'ttt':'3'})

TypeError: create_objection() takes 2 positional arguments but 3 were given

我想得到:

{'name': 'c1', 'position': {'t': 1}, 'extra_info': [{'whatever':[3453,3453]},{'whatever2':[34,34]}]}

如何进行?

【问题讨论】:

  • 发布实际的整个堆栈跟踪。问题很可能在那里被阐明。问题很可能是因为您给函数提供了太多位置参数。 **kwargs 参数意味着它接受任何关键字元素。
  • 如前所述,kwargs 用于keyword=value 类型的参数。看起来您正在使用字典作为位置参数。
  • d = {'t':1, 'whatever':[3453,3453],'whatever2':[34,34]} def create_objection(*arg, **kwargs): pass create_objection ('c', d)
  • 添加了错误和结果。还有更多解释

标签: python methods keyword-argument


【解决方案1】:

这里发生的情况是,您已经定义了一个只有两个位置参数的函数,并且您试图给它 3,正如错误消息告诉您的那样。

如果我们查看您的代码,那么您似乎也没有尝试使用关键字参数,因此不会使用 **kwargs 参数。

只需对您的代码稍作改动,我们就能得到您想要的结果:

def create_objection(name, position, *args):
    dicct = {'name': name,
             'position': position}
    if args:
        dicct["extra_info"] = args
    return dicct

x = create_objection('c1', {'t': 1})
z = create_objection('c1', {'t': 1}, {'whatever': [3453, 3453]}, {'whatever2': [34, 34]})

print(x)
print(z)

输出:

{'name': 'c1', 'position': {'t': 1}}
{'name': 'c1', 'position': {'t': 1}, 'extra_info': ({'whatever': [3453, 3453]}, {'whatever2': [34, 34]})}

如果您还想包含其他关键字参数,那么您可以像这样对该变量执行另一个循环:

def create_objection(name, position, *args, **kwargs):
    dicct = {'name': name,
             'position': position}
    if args:
        dicct["extra_info"] = args
    for key, value in kwargs.items():
        dicct[key] = value
    return dicct

y = create_objection('c1', {'t': 1}, {'whatever': [3453, 3453]}, thisisakeyword="totally a keyword!")
print(y)

输出:

{'name': 'c1', 'position': {'t': 1}, 'extra_info': ({'whatever': [3453, 3453]},), 'thisisakeyword': 'totally a keyword!'}

【讨论】:

    【解决方案2】:

    Here is a similar issue

    看起来你需要在调用你的函数时解包你的字典。

    create_objection('c1',{'t':1},**{'whatever':[3453,3453]},{'whatever2':[34,34]})
    

    注意**

    【讨论】:

      【解决方案3】:

      试试:

      def create_objection(*args, **kwargs):
         dicct = {'name': args[0], 'position': args[1]}
         if not kwargs:
             print(len(kwargs))
             dicct.update{{'extra_info': kwargs})
         return dicct
      

      忽略上述内容,将其留到下一部分,但 OP 必须将方法更改为:

      def create_objection(name=None, position=None, **kwargs):
         dicct = {'name': name, 'position': position}
         if not kwargs:
             print(len(kwargs))
             dicct.update{{'extra_info': kwargs})
         return dicct
      

      【讨论】:

      • 这种方法是否可以扩展为具有位置参数,*args AND **kwargs??
      • *args 是一个列表,**kwargs 是一个字典。由于这解决了您当前的问题,请使用它并为您的下一个问题发布另一个问题
      • 这样的缺点是我不能用 objection=create_objection(name='XY', position='pos3') 调用方法
      • 查看我在答案中附加的文字
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-27
      • 2012-12-20
      • 1970-01-01
      • 2020-08-22
      • 1970-01-01
      • 1970-01-01
      • 2016-06-08
      相关资源
      最近更新 更多