7

I'm a Python beginner and I am from C/C++ background. I'm using Python 2.7.

I read this article: A Beginner’s Guide to Python’s Namespaces, Scope Resolution, and the LEGB Rule, and I think I have some understanding of Python's these technologies.

Today I realized that I can write Python code like this:

if condition_1:
    var_x = some_value
else:
    var_x = another_value
print var_x

That is, var_x is still accessible even it is not define before the if. Because I am from C/C++ background, this is something new to me, as in C/C++, var_x are defined in the scope enclosed by if and else, therefore you cannot access it any more unless you define var_x before if.

I've tried to search the answers on Google but because I'm still new to Python, I don't even know where to start and what keywords I should use.

My guess is that, in Python, if does not create new scope. All the variables that are newly defined in if are just in the scope that if resides in and this is why the variable is still accessible after the if. However, if var_x, in the example above, is only defined in if but not in else, a warning will be issued to say that the print var_x may reference to a variable that may not be defined.

I have some confidence in my own understanding. However, could somebody help correct me if I'm wrong somewhere, or give me a link of the document that discusses about this??

Thanks.

MattDMo
  • 100,794
  • 21
  • 241
  • 231
yaobin
  • 2,436
  • 5
  • 33
  • 54
  • 1
    You are correct. Variables defined in `if`/`elif`/`else` blocks are visible in the scope containing the block. – MattDMo Jul 19 '15 at 19:42
  • 1
    This also applies to `for` and `while` loops, as well as the `with` statement. Basically everything but functions and classes (you can still access variables through the class's name: `Cls.var`). – Markus Meskanen Jul 19 '15 at 19:47
  • 1
    you can mess around looking at what is and isn't in scope with `locals()` and `globals()` – NightShadeQueen Jul 19 '15 at 19:48
  • 1
    @MarkusMeskanen you are correct. However, there are other enclosed scopes, such as comprehensions, where variables created in them are not visible to the surrounding code. – MattDMo Jul 19 '15 at 19:48
  • @MattDMo Good point. – Markus Meskanen Jul 19 '15 at 19:49
  • 1
    @MattDMo: true only for Python 3.x. With 2.x comprehension variables are defined in the surrounding scope. – Daniel Jul 19 '15 at 19:54
  • brackets = whitespace characters left Always can access if calling elements is stay left side . – dsgdfg Jul 19 '15 at 19:54
  • @Daniel interesting, I didn't know that – MattDMo Jul 19 '15 at 20:04
  • @MattDMo: I tried what Daniel said about comprehension variables in Python 2.7, and it's true. With the code `a = [n for n in range(0,10)]`, `print n`, you'll see `n` is still accessible. – yaobin Jul 19 '15 at 22:01

1 Answers1

10

My guess is that, in Python, if does not create new scope. All the variables that are newly defined in if are just in the scope that if resides in and this is why the variable is still accessible after the if.

That is correct. In Python, namespaces, that essentially decide about the variable scopes, are only created for modules, and functions (including methods; basically any def). So everything that happens within a function (and not in a sub-function) is placed in the same namespace.

It’s important to know however that the mere existance of an assignment within a function will reserve a name in the local namespace. This makes for some interesting situations:

def outer ():
    x = 5
    def inner ():
        print(x)
        # x = 10
    inner()
outer()

In the code above, with that line commented out, the code will print 5 as you may expect. That’s because inner will look in the outer scope for the name x. If you add the line x = 10 though, the name x will be local to inner, so the earlier look up to x will look in the local namespace of inner. But since it hasn’t been assigned yet, you will receive an UnboundLocalError (“local variable 'x' referenced before assignment”). The nonlocal statement was added in Python 3 to overcome one issue from this: The situation where you want to actually modify the x of the outer scope within the inner function.

For more information on name lookup, see this related question.

Community
  • 1
  • 1
poke
  • 369,085
  • 72
  • 557
  • 602
  • Thanks, and it's interesting to know the situation you mentioned here.. I've never known about this! – yaobin Jul 19 '15 at 21:55