最佳答案
我想知道 Python 是否有类似 C # 匿名类的特性:
var foo = new { x = 1, y = 2 };
var bar = new { y = 2, x = 1 };
foo.Equals(bar); // "true"
在 Python 中,我会想象这样的东西:
foo = record(x = 1, y = 2)
bar = record(y = 2, x = 1)
foo == bar # true
具体的要求是能够在表达式上下文中创建一个具有指定字段的对象(例如,在 lambdas 和其他不允许使用语句的地方可用) ,不需要额外的外部声明,并且能够通过正常的成员访问语法 foo.bar按名称访问单个组件。创建的对象还应该实现结构化比较 通过组件名称(而不是像元组那样按位置进行)。
特别是: 元组不是因为它们的组件没有命名; 类不是因为它们需要声明; dicts 不是因为它们有不需要的 foo["bar"]语法来访问组件。
Namedtuple 不是这样的,因为即使您内联定义了类型,它仍然需要一个名称,并且比较是基于位置的,而不是基于名称的。特别是:
def foo(): return namedtuple("Foo", "x y")(x = 1, y = 2)
def bar(): return namedtuple("Foo", "y x")(x = 1, y = 2)
foo() == bar() # False because fields are compared in order, and not by name
# True would be desired instead
如果需要,我知道如何用 Python 编写这样的程序。但是我想知道在 Python 标准库或任何流行的第三方库中是否有类似的东西。
这里有一个单表达式解决方案,它结合了 Ken 和 alanlcode 提供的两个信息量非常大的答案,在没有任何额外的外部声明的情况下,产生了结构相等性:
type("", (), { \
"__init__": (lambda self, **kwargs: self.__dict__.update(kwargs)), \
"__eq__": (lambda self, other: self.__dict__ == other.__dict__) } \
)(x = 1, y = 2)
从技术上讲,它满足了问题的所有要求,但我真诚地希望没有人使用它(我肯定不会)。