提问人:Drakes 提问时间:9/27/2021 更新时间:9/27/2021 访问量:60
无法比较 Python 中相同但重新声明的命名元组的类型
Unable to compare types of identical but redeclared namedtuples in Python
问:
在开发差异引擎以识别非常大的数据结构中的差异时,我注意到相同但重新声明的比较行为不端。重新声明是不可避免的*。下面是一个最小的示例:type
namedtuples
namedtuples
def test_named_tuples_same_type():
from collections import namedtuple
X = namedtuple("X", "x")
a = X(1)
# We are unable to avoid redeclaring X
X = namedtuple("X", "x")
b = X(1)
print(repr(a))
print(repr(b))
# X(x=1)
# X(x=1)
assert isinstance(type(a), type(b)) # fail
assert type(a) == type(b) # fail
断言返回:
> assert isinstance(type(a), type(b)) # fail
E AssertionError: assert False
E + where False = isinstance(<class 'tests.test_deep_diff.X'>, <class 'tests.test_deep_diff.X'>)
E + where <class 'tests.test_deep_diff.X'> = type(X(x=1))
E + and <class 'tests.test_deep_diff.X'> = type(X(x=1))
和
> assert type(a) == type(b) # fail
E AssertionError: assert <class 'tests.test_deep_diff.X'> == <class 'tests.test_deep_diff.X'>
如何断言两者的类型相等或语义相等(无)?str(type())
*重新声明是不可避免的,因为它发生在不可修改的 'd 代码中,以生成不同的数据结构。namedtuple
exec
答:
0赞
juanpa.arrivillaga
9/27/2021
#1
目前尚不完全清楚你所说的语义等价是什么意思。但请考虑:
>>> from collections import namedtuple
>>> X1 = namedtuple("X", "x")
>>> X2 = namedtuple("X", "x")
然后,您可以使用以下功能:
>>> def equivalent_namedtuple_types(t1, t2):
... return (t1.__name__, t1._fields) == (t2.__name__, t2._fields)
...
>>> equivalent_namedtuple_types(X1, X2)
True
>>>
从您的评论来看,您似乎也关心该属性。.__module__
评论
0赞
Drakes
9/27/2021
我参与了一个差异引擎。它实质上比较了两个对象,比如 和 。在检查字段是否相同之前,最合理的做法是首先检查类型是否相同。因此,给定这样一个在 99% 的时间内都能出色工作的比较器,重新声明的(在同一模块中)情况会出现并且是一个问题。鉴于我的 OP,我希望将这两个对象解释为相等,因为它们具有相同的“类”和相同的成员字段。a
b
namedtuple
0赞
juanpa.arrivillaga
9/27/2021
@Drakes好的,在检查元组是否相等之前,您可以使用上述方法检查它们是否具有相同的“类”。
下一个:额外的参数必须位于元组中
评论
X
x
X = namedtuple("X", "x")
foo
X = namedtuple("X", "x")
bar