Hi all,

I'm not sure whether this idea has been discussed before or not, so I apologize in advanced if that's the case.

Consider the behavior:

>>> f = lambda: True
>>> f.__name__
'<lambda>'
>>> x = f
>>> x.__name__
'<lambda>'

I'm arguing the behavior above is too brittle/limited and, considering that the name of the attribute is `__name__`, not entirely consistent with Python's AST. Consider:

>>> f = lambda: True
>>> x = f

At the first line, an ast.Assign would be created whose target is an ast.Name whose `id` is `f`. 
At the second line, an ast.Assign would be created whose target is an ast.Name whose `id` is `x`.
However, as you can see `__name__` special method returns 'lambda' in both cases (just like it was defined https://docs.python.org/3/library/stdtypes.html#definition.__name__), whereas I think either it should have returned '<lambda>' and 'x' or a new function/attribute should exist that does so and more.

For example, consider:

>>> x_1 = 1
>>> x_2 = 1
>>> x_3 = 1
>>> x_4 = x_1
>>> for i in [x_1, x_2, x_3, x_4]:
>>>     print(i)
1
1
1
1

Now assume such a function exist and is called `name`. Then:

>>> name(1)
'1'
>>> name("Something")
"Something"
>>> name(x_1)
'x_1'
>>> name(x_4)
'x_4'
>>> name(x_5)
'x_5' # Or an Exception!
>>> def itername(collection):
>>>     for i in map(lambda x: name(x), collection):
>>>         yield i
>>>
>>> for i in [x_1, x_2, x_3, x_4]:
>>>     print(i, name(i))
1, 'i'
1, 'i'
1, 'i'
1, 'i'
>>> for i in itername([x_1, x_2, x_3, x_4]):
>>>     print(i)
'x_1'
'x_2'
'x_3'
'x_4'


I think above example gives an idea of the behavior I'm proposing. I can implement it in a hacky way by parsing the block into ast and going through all the nodes that have an `id` or a `name` or `asname` etc, but this behavior wouldn't be pretty for run-time cases e.g. `itername` in the example above.

Anyway I'd appreciate any input.


P.S. I must confess that I can't think of a single case where having this function is the only way to do the job, if the job is sufficiently different from the specification of said function. It'd be only for the sake of convenience, and continuation of what already was there with `__name__`.