boot-scootin
boot-scootin

Reputation: 12515

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

Upvotes: 0

Views: 1774

Answers (1)

MisterMiyagi
MisterMiyagi

Reputation: 50096

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.

Upvotes: 4

Related Questions