Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does an imported function "as" another name keep its original __name__?

Here:

from os.path import exists as foo
print foo.__name__

we get: 'exists'. Why not 'foo'? Which attribute would give 'foo'?

like image 819
Basj Avatar asked Nov 13 '18 11:11

Basj


People also ask

Why do we use __ name __ in Python?

__name__ is a built-in variable which evaluates to the name of the current module. Thus it can be used to check whether the current script is being run on its own or being imported somewhere else by combining it with if statement, as shown below.

Which name does __ name __ gets compared with when imported?

The __name__ variable allows you to do that. When you run the script directly, Python sets the __name__ variable to '__main__' . However, if you import a file as a module, Python sets the module name to the __name__ variable.

What's __ name __ in Python?

The __name__ variable (two underscores before and after) is a special Python variable. It gets its value depending on how we execute the containing script. Sometimes you write a script with functions that might be useful in other scripts as well. In Python, you can import that script as a module in another script.

What will be the value of __ name __ attribute of the imported module?

The value of __name__ attribute is set to “__main__” when module is run as main program. Otherwise, the value of __name__ is set to contain the name of the module. We use if __name__ == “__main__” block to prevent (certain) code from being run when the module is imported.


Video Answer


2 Answers

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>'
like image 180
timgeb Avatar answered Oct 19 '22 22:10

timgeb


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).

like image 22
Martijn Pieters Avatar answered Oct 19 '22 22:10

Martijn Pieters