0

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
6
  • try using a relative import: from .evens import find_evens Commented Oct 12, 2016 at 14:34
  • 3
    You should pass arr in as a function argument instead, and define find_evens to take a parameter (e.g. def find_evens(arr): ... and calling it with find_evens(arr)) Commented Oct 12, 2016 at 14:34
  • Well, arr doesn't get defined in evens.py when it is being imported (because then it's not __main__). And it won't see the arr defined in import_evens.py. Commented Oct 12, 2016 at 14:44
  • I could pass that as an argument, but I would rather have these functions work on global variables Commented Oct 12, 2016 at 14:44
  • 6
    No, you wouldn't. Really, trust us, you don't want global variables. Commented Oct 12, 2016 at 14:45

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.