为什么我的模块的行为不像单例?

时间:2020-06-04 16:12:18

标签: python

我有一个JSON文件,在一个小游戏中,我将它用作学习Python的一种方式。
我精通多种其他语言。

我有几个类想要读取对JSON的访问权限,因此我想将文件中的JSON加载到变量中,然后允许其他类通过getter和setter访问变量,因为每个类都希望访问不同的部分。 JSON。

这听起来像是Singleton的工作。我知道Python模块的行为就像单例。

但是,当我将Module导入类时,变量会重置吗?

这是一个非常精简的示例:

模块:-state_manager

x=45
def set_x(value):
    x=value

def get_x():
    return x

类别:-游戏

import Player

import state_manager
value = state_manager.get_x()

类别:-玩家

import state_manager
state_manager.set_x(12)

通过设置断点,我可以看到Playerxstate_managerx的值设置为12时。

但是当我查看使用state_manager.get_x()返回给Game的int divide(int a, int b) { Q_ASSERT_X(b != 0, "divide", "division by zero"); return a / b; } 的值时,得到45。

这是为什么?

在Python中创建可以在其他类之间共享的模块或对象的正确方法是什么?

我意识到自己可以自己构造一个Singleton,但我认为我会使用Python的功能。

2 个答案:

答案 0 :(得分:3)

通过设置断点,我可以看到当Game导入Player时,Player将state_manager中的x值设置为12。

我相当确定您在检查中做错了,因为set_x函数,至少如您所引用的那样...

x=45
def set_x(value):
    x=value

...不执行您认为的操作。由于x是在set_x的范围内分配的,因此它不是引用全局(模块级)变量x,而是引用一个局部变量x set_x返回时立即被丢弃作为堆栈帧的一部分。静态分配的存在实际上是在Python中声明局部变量的方式。解决方法是声明x引用全局变量:

x=45
def set_x(value):
    global x
    x=value

答案 1 :(得分:2)

您需要在任何试图全局设置的函数中声明x全局:

def set_x(value):
    global x
    x=value

没有全局声明,x只是函数局部变量。

通常,如果函数在函数中的任何位置分配给变量,则该变量是局部变量,除非明确声明了global(或nonlocal)。如果某个函数仅读取变量而不进行设置,则该变量将从更高的范围(例如,全局引用或上级引用)中获取。

相关问题