我想知道Python是否有类似C#匿名类的功能。为了说明问题,这里有一个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
以名称访问单个组件。创建的对象还应该实现结构比较按组件名称 (而不是像图元那样按位置排列)。
特别是:图元不是它,因为它们的组件没有被命名;类不是它,因为它们需要声明;数据不是它,因为它们有不受欢迎的foo["bar"]
语法来访问组件。
命名元组不是,因为它仍然需要一个名字,即使你定义了内联类型,而且比较是基于位置的,而不是基于名字。特别是。
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标准库或任何流行的第三方库中是否有这样的东西。
[EDIT]
为了方便起见,这里有一个单一表达式的解决方案,它结合了Ken和alanlcode的两个非常丰富的答案,产生了结构上的平等,而没有任何额外的外部声明。
type("", (), { \
"__init__": (lambda self, **kwargs: self.__dict__.update(kwargs)), \
"__eq__": (lambda self, other: self.__dict__ == other.__dict__) } \
)(x = 1, y = 2)
从技术上讲,它满足了问题的所有要求,但我真诚地希望没有人使用它(我肯定不会)。