Access variable through exec

0

I was trying to create a shell to be able to communicate with a program in python during its execution, so far I have the following (this code is just an example):

import sys, pygame
from threading import Thread
import math

pygame.init()

# INIT SCREEN
size = width, height = 800, 600
screen = pygame.display.set_mode(size)
pygame.display.set_caption("teste")

black = 0,0,0
white = 255,255,255

rgb = 255,50,120

running = True

clock = pygame.time.Clock()

timer = 0
angulo = 0
x = 0
global x_var
x_var = 2

def process_input():
    while True:
        c = input("Python Shell > ")
        exec(c)



t = Thread(target=process_input)
t.daemon = True
t.start()

while running:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT: running = False
        if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: running = False


    angulo = ( angulo % 360 ) + 0.1
    sin = math.sin(angulo) * 50
    y = int( sin + height / 2)  


    x+= x_var

    pos = x,y

    rgb =  ( (rgb[0] % 255 ) +1 ) , ( (rgb[1] % 255 ) +1 ), ( (rgb[2] % 255 ) +1 )

    screen.set_at(pos, rgb)
    pygame.display.flip()

My goal would be to change a variable at runtime, for example changing x_var from 2 to -2 but I'm not succeeding. I'm a little new with python, but I've seen something similar in other situations.

I have set the variable x_var to Global until I do not know the range of the exec command. I think that having the process_input command on another thread might be affecting access, but I need to always have a loop running.

    
asked by anonymous 12.02.2018 / 13:12

1 answer

1

There are many, many snags with the way you are doing this program - but, this is part of the stuff we write when we understand how to program. The main one is that your control structures are not part of any function and are "loose" in the module code.

However, this timely question is easy to answer: exec and eval , by default your code runs in a new variable dictionary, sme no variable - but both accept as dictionary parameters to be used as the namespace of global and local variables.

Since you want to change global variables, just pass the global variables dictionary, which in Python is returned when we call globals() as the second parameter for exec :

def process_input():
    while True:
        c = input("Python Shell > ")
        exec(c, globals())

It works like this:

In [1]: b = 10

In [2]: exec(input("teste: "), globals())
teste: b = 20

In [3]: b
Out[3]: 20

If you keep and evolve this program, eventually the code inside the main pygame loop will stay in one function. You can then create a namespace object only to keep all the variables that are currently local, and pass the .__dict__ of that object as a global parameter to the exec.

    
13.02.2018 / 12:09