Reputation: 2151
A separate process calls a function whenever data is available and provides that data as the input to the called function
In the function I process the data, and want to make results of it globally available (i.e., a globally available variable changes its value dynamically)
What is a clean method to achieve this across modules, when within a module, this job would be performed well through a global variable?
I use an eyetracking device (Tobii 4C) that can provide gaze data of a human via a Python API
The typical flow would be to:
eyetracker
object, pointing to the eyetracking deviceeyetracker.subscribe_to(DATA, callback)
The callback
is a function handle that gets called everytime the eyetracking device has new data available. Typically it would be used to save data, e.g.:
# `gaze_data` is what gets returned from the eyetracking device that we subscribed to
def my_callback(gaze_data):
# fname is defined globally in this case
with open(fname, 'a') as f:
f.write(gaze_data)
The data recording would then run "in the background", until we cann eyetracker.unsubscribe()
However, to make use of "live" gaze data, one would have to make gaze_data
a global variable, e.g.,
def my_callback(gaze_data):
global gaze
gaze = gaze_data['gaze_point']
... now we can use gaze
in our script, which gets continuously "updated" whenever the callback function is run (which happens at the sampling rate of the eyetracking device)
I have a larger project, where I organize 2 modules:
eyetracker.py
where I define my callback functions and other eyetracking functionstest_eyetracker.py
where I import functions from eyetracker.py
and test themHowever, when I import the functions from eyetracker.py
into test_eyetracker.py
, the global variable gaze
is not being updated.
After a lot of search, I realized that this is because global variables are not cross-module. So when in test_eyetracker.py
the gaze
should be updated, this change is not available within the scope of test_eyetracker.py
and as such, calls like assert gaze == 'value_i_know_it_should_be'
evaluate as False.
My current solution is, to define the eyetracking functions in the script, where I also use them. However, this does not feel clean , especially, because I would like to use the eyetracking functions in several other modules (not just the test module) = code duplication.
Is there a better way to organize this?
I have come across this post that shows how builtins
are the only truly cross-module globals ... but it is discouraged to use those for a tweak that allows me a cross-module global variable.
Upvotes: 1
Views: 738
Reputation: 8530
A workaround to this problem is to use for example a global dict. I will show you a code snippet based on the linked question that demonstrates the idea:
file1.py:
global_dict = {'x': 5}
x = 5 # for comparison
file2.py:
from file1 import *
def update_x():
global x
global global_dict
x += 1
global_dict['x'] += 1
main.py:
from file2 import *
update_x()
print(x) # 5
print(global_dict['x']) # 6
Upvotes: 2