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

你的代码

```

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

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

1年前 评论

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

1年前 评论
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)
1年前 评论
184281564 (楼主) 1年前

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

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

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!