Here:
from os.path import exists as foo
print foo.__name__
we get: 'exists'
.
Why not 'foo'
? Which attribute would give 'foo'
?
Here:
from os.path import exists as foo
print foo.__name__
we get: 'exists'
.
Why not 'foo'
? Which attribute would give 'foo'
?
You can view import foo as bar
as just an assignment. You would not expect a function to change its __name__
attribute when you assign another name to the function.
>>> def foo(): pass
>>>
>>> foo.__name__
'foo'
>>> bar = foo
>>> bar.__name__
'foo'
Thanks. What attribute of the variable
bar
would return the string'bar'
then?
There is no such attribute. Names (bar
) refer to values (the function object) unidirectionally.
The __name__
attribute of a function is set as the name the function was defined with using the
def ...
syntax. That's why you don't get a meaningful __name__
attribute if you define an anonymous function and assign the name foo
after it has been created.
>>> foo = lambda: None
>>> foo.__name__
'<lambda>'
Importing an object just binds a new variable, and all that adding as newname
does is let you pick an alternative name to use for the variable in the current namespace.
The __name__
attribute on an object says nothing about the name it is currently bound to, you can have any number of variables as well as containers such as lists or dictionaries pointing to the same object, after all:
def foo(): pass
bar = foo
spam = foo
list_of_functions = [foo]
dictionary_of_functions = {'monty': foo, 'python': foo}
The above created 4 additional references to the function object; you can't have foo.__name__
reflect all of those, and the references in list_of_functions
and dictionary_of_functions
do not (directly) have names.
Since import foo
, import bar as foo
, from module import foo
and from module import bar as foo
all just set the name foo
in the current module, they are treated the exact same way as other assignments. You could import the function more than once, under different names, too.
Instead, the __name__
value of a function is set to name it was defined with in the def <name>(...):
statement. It is a debugging aid, at most. It is used in tracebacks, for example, to make it easier to identify lines of code shown in the traceback. You'd only set the __name__
to something else if that would help identify the location better. (Note: in Python 3, there is also the __qualname_
attribute, which is used instead of __name__
as it includes more information on where the function is defined when nested or defined on a class).
The as
is syntactical sugar in the file/session of the import, while the __name__
attribute is part of the function object.