Python - Acceder y modificar variable global en otro módulo

 
Vista:
sin imagen de perfil
Val: 13
Ha disminuido su posición en 9 puestos en Python (en relación al último mes)
Gráfica de Python

Acceder y modificar variable global en otro módulo

Publicado por Wilson (6 intervenciones) el 15/06/2019 03:02:31
Hola a todos, soy nuevo en python, he desarrollado por muchos años en otros lenguajes.
Mi duda puntual es como acceder y modificar una variable global que se encuentra en otro módulo.
Tengo tres módulos así:
1
2
#Módulo global  glo.py
done = False

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#Módulo funciones  funciones.py
import itertools
import time
import sys
import glo
 
 
#here is the animation
def animate():
    for c in itertools.cycle(['|', '/', '-', '\\']):
        if glo.done:
            break
        sys.stdout.write('\rloading ' + c)
        sys.stdout.flush()
        time.sleep(0.1)
    sys.stdout.write('\rDone!     ')

1
2
3
4
5
6
7
8
9
10
11
12
#Módulo principal  pal.py
import funciones as f
import threading
import time
import glo
 
t = threading.Thread(target=f.animate)
t.start()
 
#long process here
time.sleep(1)
glo.done = True

Quiero controlar la terminación de un proceso mediante la variable global: done - que se encuentra en el modulo glo.py. De momento este enfoque me funciona sin errores. Mi pegunta es, si este modo es el correcto?
¿Hay una forma mas adecuada para acceder a una variabe global?

Muchas gracias de antemano.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Jaime
Val: 526
Bronce
Ha mantenido su posición en Python (en relación al último mes)
Gráfica de Python

Acceder y modificar variable global en otro módulo

Publicado por Jaime (136 intervenciones) el 15/06/2019 08:36:20
Si te funciona, genial!
Yo pienso que las formas correctas es usar clases o funciones estáticas para encapsular los datos.
En python, todas la variables son publicas hasta que ud declare lo contrario. Para declarar una variable privada se usa "_". Ejemplo:
_done=False
O puedes crear una funcion, dentro del modulo funciones llamada Detener e invocarla en el principal:
1
2
def detener():
      glo.done=True

1
2
3
4
5
6
7
8
9
10
11
12
#Módulo principal  pal.py
import funciones as f
import threading
import time
import glo
 
t = threading.Thread(target=f.animate)
t.start()
 
#long process here
time.sleep(1)
detener()

Pues, si realmente el uso de la variable es así...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 13
Ha disminuido su posición en 9 puestos en Python (en relación al último mes)
Gráfica de Python

Acceder y modificar variable global en otro módulo

Publicado por Wilson (6 intervenciones) el 15/06/2019 14:44:09
Muchas gracias Jaime por tu respuesta.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 13
Ha disminuido su posición en 9 puestos en Python (en relación al último mes)
Gráfica de Python

Acceder y modificar variable global en otro módulo

Publicado por Wilson (6 intervenciones) el 17/06/2019 03:39:26
Hola a todos, retomando el tema, finalmente lo que pretendo es presentar un texto animado mientras se realiza un proceso. He creado una clase que encapsula las diferentes tareas de la idea inicial (en el módulo funciones):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#Módulo funciones  - - funciones.py
import itertools
import time
import sys
import threading
 
 
class a_busy:
    processing = False
    a_thread = None
    def __init__(self):
        pass
 
    def animate(self):
        for c in itertools.cycle(['|', '/', '-', '\\']):
            if not a_busy.processing:
                break
            sys.stdout.write('\rloading '+ c)
            sys.stdout.flush()
            time.sleep(0.1)
    sys.stdout.write('\rDone!')
 
    def begin(self):
        a_busy.processing = True
        a_busy.a_thread = threading.Thread(target=self.animate())
        a_busy.a_thread.start()
 
    def end(self):
        a_busy.processing = False

Luego la llamo así desde el módulo principal, pero la instancia de la clase: a_busy, no cambia el valor de la variable processing cuando llamo el método: end, y se queda en un bucle infinito. No se que estoy haciendo mal. Muchas gracias de antemano por su ayuda.

1
2
3
4
5
6
7
8
#Módulo principal - - ppal.py
import funciones as f
import time
 
my_busy = f.a_busy()
my_busy.begin()
time.sleep(1)
my_busy.end()
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Jaime
Val: 526
Bronce
Ha mantenido su posición en Python (en relación al último mes)
Gráfica de Python

Acceder y modificar variable global en otro módulo

Publicado por Jaime (136 intervenciones) el 17/06/2019 12:06:38
Lo que pasa es que las clases en Python son diferentes a otros lenguajes como C++ o Java.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#Módulo funciones  - - funciones.py
import itertools
import time
import sys
import threading
 
 
class a_busy:
 
    def __init__(self):
        self.processing = False
        a_thread = None
 
    def animate(self):
        for c in itertools.cycle(['|', '/', '-', '\\']):
            if not self.processing:
                break
            sys.stdout.write('\rloading '+ c)
            sys.stdout.flush()
            time.sleep(0.1)
    sys.stdout.write('\rDone!')
 
    def begin(self):
        self.processing = True
        self.a_thread = threading.Thread(target=self.animate())
        self.a_thread.start()
 
    def end(self):
        self.processing = False
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 13
Ha disminuido su posición en 9 puestos en Python (en relación al último mes)
Gráfica de Python

Acceder y modificar variable global en otro módulo

Publicado por Wilson (6 intervenciones) el 17/06/2019 15:57:39
Jaime, gracias por tu respuesta e interés, pero definitivamente no funciona. No se si exista en python alguna librería con la que pueda mostrar alguna animación mientras se completa un proceso. Para procesos con iteraciones de por medio estoy usando tqdm y me va muy bien, pero no he encontrado la forma para otros procesos que cargan archivos de excel a un dataframe de pandas. Muchas gracias.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Jaime
Val: 526
Bronce
Ha mantenido su posición en Python (en relación al último mes)
Gráfica de Python

Acceder y modificar variable global en otro módulo

Publicado por Jaime (136 intervenciones) el 17/06/2019 17:39:32
Compañero, lo malo de los lenguajes de scriptin es que hay errores de sintaxis que no se reportan. Lo que pasaba es que al crear el hilo tenias que pasar el nombre de la función más no invocarla.
Así: self.a_thread = threading.Thread(target=self.animate)
y no asi: self.a_thread = threading.Thread(target=self.animate())
Lo descubrí depurando linea por linea, y al darme cuenta que nunca llegó a la linea "time.sleep(1)" del archivo principal, empecé a buscar el por qué!
Ya funciona y lo probé
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#Módulo funciones  - - funciones.py
import itertools
import time
import sys
import threading
 
 
class a_busy:
 
    def __init__(self):
        self.processing = False
        a_thread = None
 
    def animate(self):
        for c in itertools.cycle(['|', '/', '-', '\\']):
            if not self.processing:
                break
            sys.stdout.write('\rloading '+ c)
            sys.stdout.flush()
            time.sleep(0.1)
        sys.stdout.write('\rDone!')
 
    def begin(self):
        self.processing = True
        self.a_thread = threading.Thread(target=self.animate)
        self.a_thread.start()
 
    def end(self):
        self.processing = False
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 13
Ha disminuido su posición en 9 puestos en Python (en relación al último mes)
Gráfica de Python

Acceder y modificar variable global en otro módulo

Publicado por Wilson (6 intervenciones) el 18/06/2019 04:47:39
Infinitas gracias Jaime por tu tiempo y tu ayuda. Funciona perfecto!.

Una última pregunta, ¿En tu experiencia con Python, crees que esta es una solución aceptable para el problema planteado (mostrar al usuario final que el programa está vivo mientras realiza un proceso que consume algún tiempo considerable)?

Una vez mas infinitas gracias!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Jaime
Val: 526
Bronce
Ha mantenido su posición en Python (en relación al último mes)
Gráfica de Python

Acceder y modificar variable global en otro módulo

Publicado por Jaime (136 intervenciones) el 18/06/2019 04:52:53
No lo sé, en python solo estoy aprendiendo. Antes me divertí y aprendí más con tu código!.
En sí, la idea está muy buena de mostrar alguna animación y tu código me parece muy bueno. Por lo que he visto en python, es que es muy poderoso para el manejo de datos. Yo estoy aprendiendo python es para usarlo como librerias dentro de otros lenguajes como java y c++(para interfaz gráfica). De pronto lo puedes orientar por ahí! o no sé.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 13
Ha disminuido su posición en 9 puestos en Python (en relación al último mes)
Gráfica de Python

Acceder y modificar variable global en otro módulo

Publicado por Wilson (6 intervenciones) el 18/06/2019 05:12:45
Muchas gracias Jaime, la función: animate - la encontré googleando, la clase, si decidí implementarla para finalmente evitar el uso de variables globales, que es lo que muchos recomiendan.

Yo estoy usando Python para cumplir con un requerimiento específico, también de análisis de datos, eso ya lo tengo resuelto, pero no quiero entregarlo tan pobre en la interfaz de usuario.

Esperemos la opinión de algún compañero que pase por aquí.

Una vez mas, muchas gracias.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar