Home > Net >  Python class variable is None despite being set
Python class variable is None despite being set

Time:10-23

I'm struggling with thread communication in Python. I'm clearly missing something, but I'm new to Python so I don't know very well what I'm doing.

When the server gets a GET request, I want it to get two numbers (x and y coords) from a separate thread, which constantly updates those values and to return those numbers as a response.

I have a simple Django project with the following structure:

enter image description here

it is very basic, made according to tutorial.

When the server starts, I start a thread that looks launches my coordinate generator in a separate thread:

class GpsMockCoordsServiceConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'gps_mock_coords_service'

    def ready(self):
        if os.environ.get('RUN_MAIN', None) != 'true':
            _thread.start_new_thread(CoordsTracker.launch_recognition, ())

CoordsTracker class looks like so:

coords = None
class CoordsTracker:
    #coords = None #tried placin it here, but same effect - it is None when retreived from views.py

    logger = logging.getLogger("CoordsTrackerLogger")

    @staticmethod
    def draw_contours(mask, frame, color):
            ......
        for stuff in stuffs:
                 ......
            CoordsTracker.set_coords((x, y))
                 ......

    @staticmethod
        def launch_recognition():
                ........
           while True:
                    ........
               CoordsTracker.draw_contours(....)
                    ........

   @staticmethod
   def set_coords(new_coords):
       global coords
       CoordsTracker.logger.debug("setting coords "   str(new_coords))
       coords = new_coords # here coords var is OK

   @staticmethod
   def get_coords():
       CoordsTracker.logger.debug(coords) # Here it is OK if I call this method from draw_contours() and is not OK if I call this from views.py file.
       return coords

views.py class has only this method:

def index(request):
    # with CoordsTracker.coords_thread_lock:
    coords = CoordsTracker.get_coords()
    logger.debug("Got coords: "   str(coords)) #if I do a GET request this prints 'Got coords: None'
    return HttpResponse(str(coords))

UPD: after some time debugging with a friend, we found out that it appears that the set_coords() method is called in one process, while get_coords() in another process.

CodePudding user response:

I'd recommend implementing some kind of IPC with the middleware you have. But if it's a one-off project, you can just launch the thread (launch_recognition) from wsgi.py somewhere. This will ensure it all runs in the same process.

  • Related