Name of a Python function
In Python there are three things that can be considered being name of the function:
The original name of the code block
It’s stored in the
f is the function object). If you use
def orig_name to create function,
orig_name is that name. For lambas it's
This attribute is readonly and can’t be changed. So the only way to create function with the custom name in runtime I’m aware of is
(There is also more low-level way to do this that.)
The immutability of
co_name actually makes sense: with that you can be sure that the name you see in the debugger (or just stack trace) is exactly the same you see in the source code (along with the filename and line number).
__name__ attribute of the function object
It’s also aliased to
You can modify it (
orig_name.__name__ = 'updated name') and you surely do on a daily basis:
@functools.wraps copies the
__name__ of the decorated function to the new one.
__name__ is used by tools like
pydoc, that's why you need
@functools.wraps: so you don't see the technical details of every decorator in your documentation. Look at the example:
Here is the
test1 = decorated(*args, **kwargs)
wraps there is no sign of
decorated in the documentation.
Name of the reference
One more thing that can be called function name (though it hardly is) is the name of a variable or an attribute where reference to that function is stored.
If you create function with
def name, the
name attribute will be added to the current scope.
lambda, on the other hand, just returns a new value (which also can be assigned to attribute or variable:
name = lambda: None`).
Obviously you can create more than one reference to the same function and all that references can have different names.
The only way all that three things are connected to each other is the
def foo statement that creates function object with both
__code__.co_name equal to
foo and assign it to the
fooattribute of the current scope. But they are not bound in any way and can be different from each other:
File "my.py", line 13, in <module>
File "my.py", line 7, in orig_name
name_in_module = updated name()
This article was originally posted as an answer to my own Stack Overflow question. I thank other people for comments and answers, they helped me to organize my thoughts and knowledge.