存储共享类变量的正确方法是什么?

时间:2017-03-29 16:42:11

标签: python python-3.x

一个有点简单的问题,但我想帮助理解Python中的类是如何工作的。具体来说,何时设置类变量,并且每次创建该类的实例时它们是否被覆盖?

这是一般情况。我有一个数据表,我希望某个类的所有实例都能够访问。问题是该表位于数据库服务器上。我想自动连接到数据库,并在第一次创建此类的实例时将此表检索到内存中,但不是在此之后的任何时间。

似乎类变量可以工作,但我只是想验证是否会出现这种情况。我的程序将创建这个类的数百个实例,所以我绝对不希望意外地为同一个表创建数百个数据库调用,或者在内存中存储数百个相同表的副本。

我可以写下面的内容吗?假设“get_table_from_db”是一个连接到数据库并返回带有相关表的pandas数据帧的函数。

class ExampleClass:
    table1 = get_table_from_db(arguments)
    def __init__(self, x, y):
        self.value = self.table1.iloc[x, y]

obj1 = ExampleClass(0, 0)
obj2 = ExampleClass(0, 1)

基本上,当我运行这个脚本时,我想在创建obj1之前或之后运行“get_table_from_db”一次,并将相关数据帧存储到table1。当创建obj2时,我不想再次调用“get_table_from_db”因为table1已经存在。但是,我仍然希望它能够访问table1的某些方法,因为它需要可用的数据(例如,我将self.value指定为等于表中的特定单元格,但我的实际代码是比这更复杂)。

另外,类似的问题。如果上面的方法有效,我可以从类中重置一个类变量吗?例如,以下内容是否允许我修改(并通过修改我的意思是重新下载)类的所有实例的类变量?

class ExampleClass:
    table1 = get_table_from_db(arguments)
    def __init__(self, x, y):
        self.value = self.table1.iloc[x, y]
    def reset_table(self):
        ExampleClass.table1 = get_table_from_db(arguments)

1 个答案:

答案 0 :(得分:3)

当声明类时,类变量将初始化一次(因此在创建obj1obj2之前),因此您的代码将以您的思维方式运行。

关于你的第二个问题,你应该这样做:

class ExampleClass:
    @classmethod
    def reset_table(cls):
        cls.table1 = get_table_from_db(arguments)

这样您就可以调用obj.reset_table()ExampleClass.reset_table()而无需ExampleClass的实例。