I'm wondering if Python has anything like the C# anonymous classes feature. To clarify, here's a sample C# snippet:
var foo = new { x = 1, y = 2 };
var bar = new { y = 2, x = 1 };
foo.Equals(bar); // "true"
In Python, I would imagine something like this:
foo = record(x = 1, y = 2)
bar = record(y = 2, x = 1)
foo == bar # true
The specific requirement is being able to create an object with specified fields in expression context (e.g. usable in lambdas and other places where statements aren't allowed), with no additional external declarations, and ability to access individual components by name via the normal member access syntax foo.bar
. The created object should also implement structural comparison by component names (not by position, as tuples do).
In particular: tuples isn't it because their components are not named; classes isn't it because they require a declaration; dicts isn't it because they have undesired foo["bar"]
syntax to access components.
namedtuple isn't it, because it still requires a name even if you define the type inline, and the comparison is position-based, not name-based. In particular:
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
I know how to write such a thing in Python if needed. But I would like to know if there's anything like that in the Python standard library, or any popular third-party libraries.
[EDIT]
Just for the sake of it, here's a single-expression solution that combines two very informative answers by Ken and alanlcode, yielding structural equality without any extra outside declarations:
type("", (), { \
"__init__": (lambda self, **kwargs: self.__dict__.update(kwargs)), \
"__eq__": (lambda self, other: self.__dict__ == other.__dict__) } \
)(x = 1, y = 2)
Technically, it satisfies all the requirements of the question, but I sincerely hope that no-one ever uses it (I definitely won't).
namedtuple
in intent. – Marindamarinduque