TL; DR:
Отдельный процесс вызывает функцию всякий раз, когда доступны данные, и предоставляет эти данные в качестве входных данных для вызываемой функции
В функции я обрабатываю данные и хочу сделать их результаты доступными глобально (т. Е. Глобально доступная переменная динамически меняет свое значение)
Что такое чистый метод для достижения этой цели во всех модулях, если в модуле это задание будет хорошо выполняться через глобальную переменную?
Фон
Я использую устройство для слежения за глазами (Tobii 4C), которое может предоставлять данные о человеке через Python API
Типичный поток будет:
- инициализировать
eyetracker
объект, указывающий на устройство отслеживания движений глаз
- «подписать» объект eyetracker на фактические данные:
eyetracker.subscribe_to(DATA, callback)
callback
- это дескриптор функции, который вызывается каждый раз, когда на устройстве отслеживания движений появляются новые данные. Обычно это используется для сохранения данных, например:
# `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)
Запись данных будет выполняться "в фоновом режиме", пока мы не сможем eyetracker.unsubscribe()
Однако, чтобы использовать «живые» данные взгляда, нужно сделать gaze_data
глобальной переменной, например,
def my_callback(gaze_data):
global gaze
gaze = gaze_data['gaze_point']
... теперь мы можем использовать gaze
в нашем скрипте, который постоянно «обновляется» при каждом запуске функции обратного вызова (что происходит с частотой дискретизации устройства отслеживания движений)
Проблема
У меня есть крупный проект, в котором я организую 2 модуля:
eyetracker.py
где я определяю свои функции обратного вызова и другие функции отслеживания движения глаз
test_eyetracker.py
, куда я импортирую функции из eyetracker.py
и проверяю их
Однако, когда я импортирую функции из eyetracker.py
в test_eyetracker.py
, глобальная переменная gaze
не обновляется.
После долгих поисков я понял, что это потому, что глобальные переменные не являются кросс-модульными . Поэтому, когда в test_eyetracker.py
необходимо обновить gaze
, это изменение недоступно в пределах test_eyetracker.py
, и поэтому вызовы типа assert gaze == 'value_i_know_it_should_be'
оцениваются как False.
Текущее решение
Мое текущее решение состоит в том, чтобы определить функции отслеживания движения глаз в сценарии, где я также использую их. Тем не менее, это не выглядит чистым, особенно потому, что я хотел бы использовать функции отслеживания движений в некоторых других модулях (не только в тестовом модуле) = дублирование кода.
Есть ли лучший способ организовать это?
Я сталкивался с этим постом , в котором показано, как builtins
являются единственными действительно кросс-модульными глобальными переменными ... но не рекомендуется использовать их для настройки, которая позволяет мне кросс-модульную глобальную переменная.