跨模块访问动态更改的变量

时间:2019-05-20 17:09:15

标签: python python-3.x callback global-variables global

TL; DR:

  • 只要有数据,一个单独的进程就会调用一个函数,并将该数据作为被调用函数的输入

  • 在该函数中,我处理数据,并希望全局使结果可用(即,全局可用变量会动态更改其值)

  • 什么是在模块之间实现此目标的干净方法,当在模块内部时,可以通过全局变量很好地完成这项工作?

背景

我使用的眼球追踪设备(Tobii 4C)可以通过Python API提供人的凝视数据

典型的流程是:

  1. 初始化一个eyetracker对象,指向眼球跟踪设备
  2. 将眼动追踪器对象“订阅”到实际数据: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个模块:

  1. eyetracker.py,其中定义了回调函数和其他眼动跟踪功能
  2. test_eyetracker.py,我从eyetracker.py导入函数并对其进行测试

但是,当我将功能从eyetracker.py导入到test_eyetracker.py时,全局变量gaze并未被更新。

经过大量搜索,我意识到这是因为global variables are not cross-module。因此,当应在test_eyetracker.py中更新gaze时,此更改在test_eyetracker.py范围内不可用,因此,像assert gaze == 'value_i_know_it_should_be'这样的调用将被评估为False。

当前解决方案

我当前的解决方案是在脚本中定义眼动追踪功能,我也将在其中使用它们。但是,这感觉并不干净,尤其是因为我想在其他几个模块(不仅仅是测试模块)中使用眼动追踪功能=代码重复。

是否有更好的方法来组织此活动?

我碰到了这个post,它显示了builtins是唯一真正的跨模块全局变量的方法,但是不建议使用这些方法进行调整,使我可以跨模块全局变量变量。

1 个答案:

答案 0 :(得分:1)

解决此问题的方法是使用例如全局字典。我将基于linked问题向您展示一个代码片段,以证明该想法:

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