3

For some reason this code produces error:

import os

def main():
    print(os.path.isfile('/bin/cat'))
    import os

if __name__ == '__main__':
    main()

Result:

Traceback (most recent call last):
  File "test.py", line 10, in <module>
    main()
  File "test.py", line 5, in main
    print(os.path.isfile('/bin/cat'))
UnboundLocalError: local variable 'os' referenced before assignment

Why it happens? Note that at beginning of both cases there is import os. Somehow additional import in the end of the body of a function affects whole scope of this function.

If you remove import inside the function, everything is fine (which is not surprising).

import os

def main():
    print(os.path.isfile('/bin/cat'))
    # import os

if __name__ == '__main__':
    main()

Result:

True

About possible duplicates: There are some similar questions, but regarding global variables, not imports.

dankal444
  • 3,172
  • 1
  • 23
  • 35
  • 2
    If you import os in the global scope, you're creating a global variable called `os`. If you import os in local scope, you're creating a local variable called `os`. And if you try and use a local variable in a function before it's created, you get that error. – khelwood Nov 07 '19 at 14:09

1 Answers1

1

If you import os in the global scope, you're creating a global variable called os. If you import os in local scope, you're creating a local variable called os. And if you try and use a local variable in a function before it's created, you get that error. Same as if you were explicitly assigning a variable.

The same solutions apply, if you want the import inside the function to create a global variable, you can use the global keyword:

def main():
    global os
    print(os.path.isfile('/bin/cat'))
    import os

Or you could change your local import to use a different variable name so that your use of os is unambiguous.

def main():
    print(os.path.isfile('/bin/cat'))
    import os as _os

Though obviously this is just an example for demonstration, and there's no reason in this case to reimport os inside your function when you've already imported it globally.

khelwood
  • 55,782
  • 14
  • 81
  • 108
  • Note that I do `import os` at beginning in both examples. I just still do not understand why **additional** import in the line somewhere below causes error at the beginning of the function. – dankal444 Nov 08 '19 at 13:50
  • 1
    Because if you're creating a variable called `os` within your function (which you are, with `import os`), then the interpreter regards all references to the name `os` in the function as local variables rather than global variables. That's exactly the same as all the other questions about global variable use in a function. – khelwood Nov 08 '19 at 13:54
  • Ok, so defining variable inside a function shadows whole scope of the function, not just lines after this definition? If so, that was the thing I lacked – dankal444 Nov 08 '19 at 14:05
  • Since your question said `There are some similar questions, but regarding global variables, not imports` I thought you might have known that part, since that's exactly what all those dupes are about. – khelwood Nov 08 '19 at 14:24
  • Global variables are a bit different than imports. They share a lot, but, for example, you do not need to specify imports at the beginning of each function as you have to do with global variables. I still do not know why it is so, but I think it is material for another question. – dankal444 Nov 08 '19 at 14:32