由于名称空间/键名冲突导致特定字典解包异常(TypeError)

时间:2017-05-29 06:48:55

标签: python

我的问题是:我想要可靠地捕获由多个解压缩字典的命名空间冲突引起的错误。什么是规范方式?搜索并没有真正揭示这个问题的任何帮助。

假设我有两个类似字典的变量,我想将字符串键混合在一起。它们表示类似名称空间的对象,因此我想确保它们没有任何名称冲突。我可以这样做,冲突给我一个TypeError

>>> d1 = dict(a=1)
>>> d2 = dict(a=2)
>>> format_args = dict(**d1, **d2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: type object got multiple values for keyword argument 'a'

优异。因此,当从两个关键字类型参数构造命名空间时,我可以(天真地)做这样的事情:

# test.py
from collections import OrderedDict as od

def kwargs_mash(kwargs1, kwargs2):
    try:
        # use unpacking to disallow multiple argslists to same member name
        args = od(**kwargs1, **kwargs2)
    except TypeError:
        key_conflict = next(k for k in kwargs1 if k in kwargs2)
        # more descriptive error message
        raise TypeError('Multiple argument sets provided under member name: {}.'.format(key_conflict)) from None

但是,尝试解包非映射类型的对象也会产生TypeError

>>> x=1
>>> d=dict(**x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: type object argument after ** must be a mapping, not int

这是一个问题,因为传递给kwargs_mash的参数可能不是Mapping个对象,而我改进的,更具描述性的TypeError消息将不再是一个很好的描述发生了什么。

我的解决方案如下,并且有效。

def kwargs_mash(kwargs1, kwargs2):
    try:
        # use unpacking to disallow multiple argslists to same member name
        args = od(**kwargs1, **kwargs2)
    except TypeError as exc:
        if 'multiple values for keyword argument' in str(exc):
            key_conflict = next(k for k in kwargs1 if k in kwargs2)
            # more descriptive error message
            raise TypeError('Multiple argument sets provided under member name: {}.'.format(key_conflict)) from None
        else:
            raise

然而,this answer to another question称这种做法“脆弱”,我倾向于同意。

  

这是Python。必须有更好的方法。

更新

也许最好的办法就是:

def kwargs_mash(kwargs1, kwargs2):
    # ensure compatible arguments
    kwargs1, kwargs2 = od(**kwargs1), od(**kwargs2)
    # continue as before...

0 个答案:

没有答案