zoukankan      html  css  js  c++  java
  • 记一次诡异的bug

      使用django做项目,在视图函数中需要查询,查询前构造一个查询参数的模型来过滤参数防止报错,然后调用模型的方法返回一个字典,包括了所有查询的字段和值,发现只要查询过一次之后,后续的访问查询结果会在之前的查询模型上修改,也就是在view中把模型实例化一次之后,后边的操作都会带着之前的痕迹,如下

    模型

    class CmdbModel:
        base_model_dict = {
            "inst_id": "",
            "uuid": "",
        }
        model_dict = {}
    
        def __init__(self,partial, modify, except_keys = None, **kwargs):
            self.__set_model(partial= partial, modify= modify, **kwargs)
            if except_keys:
                for key in except_keys:
                    self.model_dict.pop(key)
        
        def __set_model(self, partial=False, modify=False, **kwargs):
            pop_list = [key for key in self.model_dict]
            for k in self.model_dict:
                if k in kwargs:
                    self.model_dict[k] = kwargs[k]
                    pop_list.remove(k)
            if partial is True:
                for pop_key in pop_list:
                    self.model_dict.pop(pop_key)
            if modify is True:
                if "inst_id" in self.model_dict:
                    self.model_dict.pop("inst_id")
        def get_model(self):
            return self.model_dict
            
    class HostModel(CmdbModel):
        model_dict = dict({
            "host_alias": "",
            "host_cpu": "",
            "host_disk": "",
            "host_health_info": "",
            "comment": "",
            "owner": "",
            "host_system": "",
            "host_env": "",
        }, **CmdbModel.base_model_dict)

     调用

    host_model = HostModel(
                    partial=True,
                    modify=False,
                    **query_dict
                )
    data,count = host_obj.list(start=start, limit=limit, **host_model.get_model())

    就是这样

    查了一下发现是因为模型的模块是使用form ... import ... 这样引入的,这样是单例模式证据就是在CmdbModel中增加一个类方法

    @classmethod
    def test(cls):
        print(cls.__init__)

    打印结果如下

    <function CmdbModel.__init__ at 0x7f5c2cab9598>
    <function CmdbModel.__init__ at 0x7f5c2cab9598>
    <function CmdbModel.__init__ at 0x7f5c2cab9598>
    <function CmdbModel.__init__ at 0x7f5c2cab9598>
    <function CmdbModel.__init__ at 0x7f5c2cab9598>
    <function CmdbModel.__init__ at 0x7f5c2cab9598>
    <function CmdbModel.__init__ at 0x7f5c2cab9598>
    <function CmdbModel.__init__ at 0x7f5c2cab9598>
    <function CmdbModel.__init__ at 0x7f5c2cab9598>
    <function CmdbModel.__init__ at 0x7f5c2cab9598>

    看见了没,所有的init都是同一个地址,证明是单例模式

    解决方法就是把self里面的成员不修改了,改成使用局部变量吧

    不知道有没有办法强制不使用单例模式呢?

  • 相关阅读:
    《Google 软件测试之道》摘录
    UIRecorder环境搭建及录制实现
    网易《人性的哲学与科学》笔记
    网易《公正:该如何做是好?》笔记(不定时更新)
    自助饮料机实现
    网易《社会心理学》笔记(不定时更新)
    uiautomator +python 安卓UI自动化尝试
    doc
    doc
    doc
  • 原文地址:https://www.cnblogs.com/wuxie1989/p/9674744.html
Copyright © 2011-2022 走看看