Access variable via exec

Asked

Viewed 160 times

0

I was trying to create a "shell" to be able to communicate with a python program 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 change x_var of 2 for -2 but I’m not succeeding. I’m a little young with python, but I’ve seen something similar in other situations.

I put the variable x_var as Global until I don’t know the range of the command exec. I think the fact that you’re in charge process_input another thread may be affecting access, but I always need to have a loop running.

1 answer

2


There are many, many snags with the way you are doing this program - but, this is part of the things we write when we’re understanding how to program.
The main thing is that its control structures are not part of any function and are "loose" in the module code.

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

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

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

It works that way:

In [1]: b = 10

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

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

If you maintain and evolve this program, eventually the code within the pygame’s main loop will be in a function. You can then create a namespace object just to keep all the variables that are currently local, and pass the .__dict__ of that object as a global parameter for exec.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.