首页 > 解决方案 > 跨模块访问动态变化的变量

问题描述

TL;博士:

背景

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

典型的流程是:

  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但是,当我从into导入函数时test_eyetracker.py,全局变量gaze没有被更新。

经过大量搜索,我意识到这是因为全局变量不是跨模块的。因此,当在test_eyetracker.py应该gaze更新时,此更改在范围内不可用,test_eyetracker.py因此,调用assert gaze == 'value_i_know_it_should_be'评估为 False。

当前解决方案

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

有没有更好的方法来组织这个?

我遇到过这篇文章,它展示builtins了唯一真正的跨模块全局变量是如何...

标签: pythonpython-3.xcallbackglobal-variablesglobal

解决方案


解决此问题的方法是使用例如全局字典。我将根据演示该想法的链接问题向您展示一个代码片段:

文件 1.py:

global_dict = {'x': 5}
x = 5 # for comparison

文件2.py:

from file1 import *

def update_x():
    global x
    global global_dict
    x += 1
    global_dict['x'] += 1

主要.py:

from file2 import *

update_x()
print(x) # 5
print(global_dict['x']) # 6

推荐阅读