NameError when importing function from another script?
<p>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 (<code>arr</code>)?</p>

<p><strong>evens.py</strong></p>

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

if __name__ == '__main__':

    arr = list(range(11))

    print(find_evens())
</code></pre>

<p><strong>import_evens.py</strong></p>

<pre><code>from evens import find_evens

if __name__ == '__main__':

    arr = list(range(11))

    print(find_evens())
</code></pre>

<p><strong>Traceback</strong></p>

<pre><code>Traceback (most recent call last):
  File "C:\Users\user\Desktop\import_evens.py", line 7, in &lt;module&gt;
    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
</code></pre>

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

<p>Since you are defining <code>arr</code> inside of <code>if __name__ ...</code>, the name <code>arr</code> is only the defined in the <em>executed</em> module. The name <code>evens.arr</code> is never defined.</p>

<p>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 <code>a_module.global_variables_name</code>. It can also be imported as <code>from a_module import global_variables_name</code>, but this is just sugar for importing it and binding it to a <em>new</em> local name.</p>

<pre><code># same as `from a_module import global_variables_name`
import a_module
global_variables_name = a_module.global_variables_name
</code></pre>

<hr>

<p>What you have shown is best done via parameters to the function:</p>

<pre><code># 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))
</code></pre>

<p>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.</p>

python python-import