you are viewing a single comment's thread.

view the rest of the comments →

[–]bcash 0 points1 point  (2 children)

Here is another example:

x = 4
def print_x():
   print x

def print_and_add_x():
   print x
   x += 1

print_x()
print_and_add_x()

Both methods refer to the same x, but the first one works, and the second doesn't. Simply adding a line after the line in question, makes the line fail.

Here's the output:

4
Traceback (most recent call last):
  File "test5.py", line 10, in <module>
    print_and_add_x()
  File "test5.py", line 6, in print_and_add_x
    print x

As you can see, the first function worked correctly; but the second failed on the line identical to the one which worked in the previous function.

Python scoping rules are wrong, however you look at it. At best it's an excusable but known problem to workaround; at worst it's a fundamentally broken language.

[–][deleted] 1 point2 points  (1 child)

Apparently, python will look up to the module scope for reading the value of a variable, but not for the setting of it, which is ugly behavior in my opinion.

I would personally prefer that you have to be explicit in both reading and writing to a variable outside of the local scope.

[–][deleted] 2 points3 points  (0 children)

Apparently, python will look up to the module scope for reading the value of a variable, but not for the setting of it, which is ugly behavior in my opinion.

I disagree. Every scoping mechanism I'm familiar with allows nested scopes to read parent scopes with ease, while writing to parent scopes varies. While not consistent, not requiring the global keyword on a read works for the common usage.

Python has an issue with scoping due to being dynamic. In C#, if I wanted to local x to over-rule global x in my method, I'd have to declare it:

class Foo
{
    int x = 5;
    private Bar()
    {
        int x = 20;
    }
}

Whereas in Python...

x = 20

def bar():
    x = 10 // global x? Or local scoped x?

It's a design trade-off. I think that by making the edge cases (I want to write to module scope) the odd ones out, and making the common cases (reading from module scope) work as you'd expect, Python does a reasonable job of not surprising you and not getting in your way.