Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter('name'), the call f(r) returns r.name. After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date). After h = attrgetter('name.first', 'name.last'), the call h(r) ret
| 238 | # Generalized Lookup Objects **************************************************# |
| 239 | |
| 240 | class attrgetter: |
| 241 | """ |
| 242 | Return a callable object that fetches the given attribute(s) from its operand. |
| 243 | After f = attrgetter('name'), the call f(r) returns r.name. |
| 244 | After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date). |
| 245 | After h = attrgetter('name.first', 'name.last'), the call h(r) returns |
| 246 | (r.name.first, r.name.last). |
| 247 | """ |
| 248 | __slots__ = ('_attrs', '_call') |
| 249 | |
| 250 | def __init__(self, attr, /, *attrs): |
| 251 | if not attrs: |
| 252 | if not isinstance(attr, str): |
| 253 | raise TypeError('attribute name must be a string') |
| 254 | self._attrs = (attr,) |
| 255 | names = attr.split('.') |
| 256 | def func(obj): |
| 257 | for name in names: |
| 258 | obj = getattr(obj, name) |
| 259 | return obj |
| 260 | self._call = func |
| 261 | else: |
| 262 | self._attrs = (attr,) + attrs |
| 263 | getters = tuple(map(attrgetter, self._attrs)) |
| 264 | def func(obj): |
| 265 | return tuple(getter(obj) for getter in getters) |
| 266 | self._call = func |
| 267 | |
| 268 | def __call__(self, obj, /): |
| 269 | return self._call(obj) |
| 270 | |
| 271 | def __repr__(self): |
| 272 | return '%s.%s(%s)' % (self.__class__.__module__, |
| 273 | self.__class__.__qualname__, |
| 274 | ', '.join(map(repr, self._attrs))) |
| 275 | |
| 276 | def __reduce__(self): |
| 277 | return self.__class__, self._attrs |
| 278 | |
| 279 | class itemgetter: |
| 280 | """ |
no outgoing calls
searching dependent graphs…