I propose an enhancement based on this issue #46151.
Currently attrgetter accepts dotted path while getting attributes from an object. I propose it should not only accept dotted paths, but other separators as well. Like this:
Allowing different types of separators in attrgetter will help users by a nested attribute path which is not dotted (could be something else such as underscore, or slash).
For example, in Django, they use __ as nested relation in ORM. Hence if we define the following code a nested relation (simplified example):
class B:
name = 'A'
class A:
b = B()
Then in Django, you should be able to get data for B from A (only in ORM, not in actual objects) then you can use the following code.
A.objects.values('b__name')
If we allow separators in attrgetter, then we can resonate this behavior at object level.
>>a = A.objects.create(**kwargs) # its an example relevant to Django
>>print(attrgetter(a, 'b__name'))
A
If we allow having separator, it will be bit more consistent for users of attrgetter and it should be a simple enough change.
As noted in issue #46151, the operator module was intended to and generally does expose internal functions, as they are coded in C in CPython, to Python itself. That issue created a small special-case exception to facilitate the use of attrgetter as a key function in .sort and other methods and functions. The previous option was to instead write a lambda function. I do not believe that #46151 intended to generally open operator and attrgetter to additions beyond the functions exposed.
attrgetter(string) returns a function meant to be called with an object that has an attribute named by the string. In the example above, attrgetter(a, 'b__name') must instead be attrgetter('b__name')(a). If one is passing a string linteral, as is the usual case I think, one can just as well, and even easier, pass the normal, legal python syntax. attrgetter('b.name')(a) works now, as I just verified.
If one wants to pass python object attribute names in string variables with app-specific non-pyobject syntax, such as s='b__name', it is not unreasonable to have the app or app user provide a conversion function. In this case,
def at(s): return s.replace('__', '.') # Convert Django ORM attr name to python object dotted name.
j = 'b__name'
attrgetter(at(j))(a)
# prints 'A' (verified)
(The use of .replace was suggested by sobolevn in a comment.