joel
joel

Reputation: 7877

Getter functions for properties and dataclass attributes

tl;dr I'm after a shorthand for lambda x: x.bar

If I have a class

class Foo:
    def bar(self) -> int:
        return 0

I can use Foo.bar as a first-class function for getting the bar attribute from a Foo, like

foo = Foo()
getter = Foo.bar
getter(foo)  # 0

This is useful when some function expects the data and getter as separate objects, and saves having to write lambda x: x.bar(). That's all fine. What I'd like is something similar with @propertys and @dataclass attributes. Here's the same approach not working for properties

class Foo:
    @property
    def bar(self) -> int:
        return 0

foo = Foo()
getter = Foo.bar
getter(foo)
Traceback (most recent call last):
  File "....py", line 16, in <module>
    getter(foo)
TypeError: 'property' object is not callable

Anyone know a way to do this?

Upvotes: 2

Views: 257

Answers (1)

Brian61354270
Brian61354270

Reputation: 14434

It sounds like you're looking for operator.attrgetter:

>>> from operator import attrgetter

>>> getter = attrgetter('bar') 
>>> getter(foo)
0

The same approach naturally works with dataclass attributes as well:

>>> @dataclass
>>> class Baz:
...    bar: int

>>> getter(Baz(1))
1

Upvotes: 2

Related Questions