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里面的成员不修改了,改成使用局部变量吧

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

  • 相关阅读:
    hdu 3709 Balanced Number 数位dp
    通过大数据分析典型的长尾问题场景及解法
    【无人驾驶技术揭秘】从机器学习角度揭秘学习型避障小车的设计思路
    Git Flow——Git团队协作最佳实践
    【技术合集】新春来袭,锦囊妙计助程序员过个好年
    【最佳编程实践】编写「可读」代码的实践
    【开发工具推荐】31款轻量高效的开源JavaScript插件和库
    【微服务那些事】Microservices场景下的持续部署
    前端图像处理指南
    Sed&awk笔记之awk
  • 原文地址:https://www.cnblogs.com/wuxie1989/p/9674744.html
Copyright © 2011-2022 走看看