why exec('print(x)') is executed while print(x) goes wrong in this python code?

Viewed 73
def build(s, loc):
    exec(s, loc)
    return loc

def main():
    L = build('x = 1', locals())
    locals().update(L)
    exec('print(x)')

  
if __name__ == '__main__':  
    main()

When I run the code above, the python console will show '1'.

def build(s, loc):
    exec(s, loc)
    return loc

def main():
    L = build('x = 1', locals())
    locals().update(L)
    print(x)
  

if __name__ == '__main__':  
    main()

When I run the code above, it will show 'name 'x' is not defined'.

What is the difference between them?

I modified my code for reducing ambiguity, a similar problem persists.

def main():
    exec('x = 1')
    exec('print(x)')
    
  
if __name__ == '__main__':  
    main()

This will show '1'.

def main():
    exec('x = 1')
    print(x)
    
  
if __name__ == '__main__':  
    main()

This will go wrong.

1 Answers

This is related to scope.

When doing this:

def main():
    exec('x = 1')
    print(x)


if __name__ == '__main__':  
    main()

The x variable defined by exec, which is local, is not the same x variable as the one passed to the print() function, which is global. Unless you tell it to be:

def main():
    exec('global x;x = 1')
    print(x)
    
  
if __name__ == '__main__':  
    main()

This ended up working for me, it prints 1.

This is because after using the global keyword on the x variable in exec(), you're telling the interpreter that despite being in a local scope, any further references to the x variable will reference the outer, global, x variable.

Related