not_a_robot not_a_robot - 1 month ago 7
Python Question

NameError when importing function from another script?

I am having difficulty importing a function from another script. Both of the scripts below are in the same directory. Why can't the function from another script handle an object with the same name (

arr
)?

evens.py

def find_evens():
return [x for x in arr if x % 2 == 0]

if __name__ == '__main__':

arr = list(range(11))

print(find_evens())


import_evens.py

from evens import find_evens

if __name__ == '__main__':

arr = list(range(11))

print(find_evens())


Traceback

Traceback (most recent call last):
File "C:\Users\user\Desktop\import_evens.py", line 7, in <module>
find_evens()
File "C:\Users\user\Desktop\evens.py", line 2, in find_evens
return [x for x in arr if x % 2 == 0]
NameError: name 'arr' is not defined

Answer

Modules in python have separate namespaces. The qualified names evens.arr and import_evens.arr are separate entities. In each module, using just the name arr refers to the one local to it, so arr in import_evens is actually import_evens.arr.

Since you are defining arr inside of if __name__ ..., the name arr is only the defined in the executed module. The name evens.arr is never defined.

Further, there is no notion of truly global names. A name can be global to a module, so all entities inside it can use it. Any other module still has to address it as a_module.global_variables_name. It can also be imported as from a_module import global_variables_name, but this is just sugar for importing it and binding it to a new local name.

# same as `from a_module import global_variables_name`
import a_module
global_variables_name = a_module.global_variables_name

What you have shown is best done via parameters to the function:

# evens.py
def find_evens(arr):
    return [x for x in arr if x % 2 == 0]

# import_evens.py
if __name__ == '__main__':
    arr = list(range(11))
    print(find_evens(arr))

If you think it's better to have global variables for this but don't understand how a language uses global variables, it's better not to have global variables.

Comments