1
def foo(i):
  print len(A)
  return i < len(A)

if __name__ == '__main__':
  A = [12]
  print A 
  foo(10)

How can foo know about A?

I am writing this because stackoverflow insists that I write some more words.

Christian Ternus
  • 8,406
  • 24
  • 39
Pratik Deoghare
  • 35,497
  • 30
  • 100
  • 146
  • 1
    A is a global name. It is visible to the functions in the same namespace, aka the current module. – CppLearner Oct 16 '13 at 21:40
  • since you do it in `if __name__ == "__main__":` any variables are part of the global namespace ... which is searched if a variable cant be found in the local namespace ... if you created it in a function named main it would not be visible outside of that function unless it was explicitly declared as global – Joran Beasley Oct 16 '13 at 21:40
  • This question (http://stackoverflow.com/questions/291978/short-description-of-python-scoping-rules) has more information about how scope works in python. Basically `if` statements don't create a new scope so `A` is in the global scope. – axblount Oct 16 '13 at 21:43

3 Answers3

5

Check the generated bytecode:

>>> dis.dis(foo)
  2           0 LOAD_GLOBAL              0 (print) 
              3 LOAD_GLOBAL              1 (len) 
              6 LOAD_GLOBAL              2 (A) 
              9 CALL_FUNCTION            1 (1 positional, 0 keyword pair) 
             12 CALL_FUNCTION            1 (1 positional, 0 keyword pair) 
             15 POP_TOP              

  3          16 LOAD_FAST                0 (i) 
             19 LOAD_GLOBAL              1 (len) 
             22 LOAD_GLOBAL              2 (A) 
             25 CALL_FUNCTION            1 (1 positional, 0 keyword pair) 
             28 COMPARE_OP               0 (<) 
             31 RETURN_VALUE

To load the A variable it uses the LOAD_GLOBAL opcode. So, when the function runs (and not at definition) it will search for this variable in the global namespace

JBernardo
  • 32,262
  • 10
  • 90
  • 115
4

A is a global variable. You may be thinking that it is local to the if __name__ == '__main__' block, but if statements do not create a separate namespace in Python. When foo is executed (not defined) the variable A exists in the global namespace so your current code runs without any issues.

If you want to see your expected behavior move everything from that block into a function and then call that from within the if __name__ == '__main__' block:

def foo(i):
  print len(A)      # A is local to main(), so this will raise an exception
  return i < len(A)

def main():
  A = [12]
  print A 
  foo(10)

if __name__ == '__main__':
  main()
Community
  • 1
  • 1
Andrew Clark
  • 202,379
  • 35
  • 273
  • 306
2

Because A is defined in the global scope, and isn't looked up in the function until it's called.

It's the same reason

def should_fail():
   print undefined_variable

print "runs OK!"

runs OK.

Christian Ternus
  • 8,406
  • 24
  • 39