Python 类属性为dict,第二次修改时,为什么出现两个不同的值

Python 类属性为 dict, 第二次修改时,为什么出现两个不同的值??
1、当这个类属性修改几次后,每次查看该类属性时,可能得到的结果不一样,请问是为什么?

2、使用 add_user_data_access_rule 这个方法修改后,每次获取 data_access_rule_dict 的结果不一样

3、调用 clear_data_access_rule_dict 方法后,有时候会得到之前的结果,有时候会得到空字典

import logging
from threading import Lock
import gc
logger = logging.getLogger(_name)

class DataAccessRuleCache(object):
data_access_rule_dict = {}
lock = Lock()

def __new__(cls, *args, **kw):
    if not hasattr(cls, '_instance'):
        ori = super(DataAccessRuleCache, cls)

    cls._instance = ori.__new__(cls, *args, **kw)
    cls._instance.__dict__ = cls.data_access_rule_dict

    return cls._instance

@classmethod
def clear_data_access_rule_dict(cls):
    cls.data_access_rule_dict = {}

@classmethod
def add_user_data_access_rule(cls, which_database, user_id, data_access_rule):
    if not cls.__check_which_database_user_data_access_rule_exists(which_database):
        cls.data_access_rule_dict.update({which_database: {}})

    if str(user_id) not in cls.data_access_rule_dict[which_database]:
        cls.data_access_rule_dict[which_database].update({str(user_id): data_access_rule})
    else:
        cls.data_access_rule_dict[which_database][str(user_id)] = data_access_rule

@classmethod
def __check_which_database_user_data_access_rule_exists(cls, which_database):
    if which_database not in cls.data_access_rule_dict.keys():
        return False

    return True

@classmethod
def check_user_data_access_rule_exists(cls, which_database, user_id):
    if which_database not in cls.data_access_rule_dict.keys():
        return False

    user_data_access_rule_dict = cls.data_access_rule_dict[which_database]
    if str(user_id) not in user_data_access_rule_dict:
        return False

    return True

@classmethod
def get_user_data_access_rule(cls, which_database, user_id):
    if not cls.check_user_data_access_rule_exists(which_database, user_id):
        return []

    user_data_access_rule_list = cls.data_access_rule_dict[which_database][str(user_id)]

    return user_data_access_rule_list
讨论数量: 12
Jason990420

Any code about how you call the methods and get the result to duplicate the issues you mentioned here ?

  1. 代码格式错误,缩格不对,请参考以下内容,再重新编辑内容.

代码高亮

```python

你的代码

```

2年前 评论
184281564 (楼主) 2年前
Jason990420

代码无法运行,当然也无法重现问题

2年前 评论

是的,本地运行重现不了,部署在 docker 上出现

2年前 评论
Jason990420

那就没办法检查,只能猜一下~

DataAccessRuleCache.add_user_data_access_rule(WhichDatabaseEnum.Odoo10Database.name, user_id, data_access_condition_list)

如果 data_access_condition_list 是一个列表,那在类方法的调用时,就会是传址,如果你别的代码有变更到其内容,那 DataAccessRuleCache.data_access_rule_dict 也会跟着变动.

@classmethod
def add_user_data_access_rule(cls, which_database, user_id, data_access_rule):
    if not cls.__check_which_database_user_data_access_rule_exists(which_database):
        cls.data_access_rule_dict.update({which_database: {}})

    if str(user_id) not in cls.data_access_rule_dict[which_database]:
        cls.data_access_rule_dict[which_database].update({str(user_id): data_access_rule})
    else:
        cls.data_access_rule_dict[which_database][str(user_id)] = data_access_rule


如果列表 a 只是一层的值列表,可以使用浅复制,如 a[:], list(a)a.copy().

@classmethod
def add_user_data_access_rule(cls, which_database, user_id, data_access_rule):
    if not cls.__check_which_database_user_data_access_rule_exists(which_database):
        cls.data_access_rule_dict.update({which_database: {}})

    if str(user_id) not in cls.data_access_rule_dict[which_database]:
        cls.data_access_rule_dict[which_database].update({str(user_id): data_access_rule.copy()})
    else:
        cls.data_access_rule_dict[which_database][str(user_id)] = data_access_rule.copy()


如果列表 a 不只是一层的值列表,就必须调用 copy.deepcopy 来深复制,如

from copy import deepcopy
b = deepcopy(a)
2年前 评论
184281564 (楼主) 2年前

这个问题什么办法改进吗?感觉我每次修改 data_access_rule_dict 这个变更,内存就会备份一个新的数据,

2年前 评论
Jason990420 2年前
184281564 (作者) (楼主) 2年前
Jason990420 2年前
184281564 (作者) (楼主) 2年前
184281564 (作者) (楼主) 2年前