zoukankan      html  css  js  c++  java
  • python实例化类,数据混乱、串内容问题(可变类型属性的初始化)

    一般情况下,我们知道 在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象

    当把list和dict当参数传入函数时,强制为引用传值(即:在函数内部修改了对象,函数外部的对象也会改变)

    def update_remark(data):
        print('函数里修改了remak为:已修改')
        data['remark'] = '已修改'
        return data['remark']
    
    
    dict1 = {'remark': '测试'}
    print('外面里remark:', end=' ')
    print(dict1)
    
    update_remark(dict1)
    
    print('外面里remark:', end=' ')
    print(dict1)

    执行结果如下:

    这个问题也不大,写函数的时候注意一下就好了。


    问题是:一个类实例化出两个对象,修改各自对象的属性,数据还能被引用了?? 

    测试代码如下:

    class Demo:
        name = ''
        data = {}
    
        def __init__(self):
            pass
    
        def set_name(self, name):
            self.name = name
    
        def get_name(self):
            return self.name
    
        def set_data(self, key, value):
            self.data[key] = value
    
        def get_data(self, key):
            return self.data[key] if key in self.data else None
    
    
    if __name__ == '__main__':
        obj1 = Demo()
        obj2 = Demo()
    
        print(obj1)
        print(obj2)
    
        obj1.set_name('实例1')
        obj2.set_name('实例2')
    
        print(obj1.get_name())
        print(obj2.get_name())
    
        obj1.set_data('remark', '测试')
    
        print(obj1.get_data('remark'))
        print(obj2.get_data('remark'))

    执行结果如下:

    这下就头大了,我只修改了obj1对象里的 data 属性,为何 obj2 里的 data 属性也跟着变了??

    实例化对象之后,可变类型的属性居然还是引用传值的??


    解决办法:不要直接在类的顶部里初始化属性,在构造方法里初始化属性才不会出错

    类顶部的属性可以直接不写,在 __init__ 构造函数里用"self.属性名 = 属性值" 这种方式设置类的属性就可以了

    注:强迫症一定要在类的顶部写属性的话,__init__ 里也还重新初始化一下

    修改后的类如下:

    class Demo:
        def __init__(self):
            self.name = ''
            self.data = {}
    
        def set_name(self, name):
            self.name = name
    
        def get_name(self):
            return self.name
    
        def set_data(self, key, value):
            self.data[key] = value
    
        def get_data(self, key):
            return self.data[key] if key in self.data else None
    
    
    if __name__ == '__main__':
        obj1 = Demo()
        obj2 = Demo()
    
        print(obj1)
        print(obj2)
    
        obj1.set_name('实例1')
        obj2.set_name('实例2')
    
        print(obj1.get_name())
        print(obj2.get_name())
    
        obj1.set_data('remark', '测试')
    
        print(obj1.get_data('remark'))
        print(obj2.get_data('remark'))

    执行结果如下:


    不知道是Python的bug还是本来就是这样设计的,总之:引以为戒!!

  • 相关阅读:
    小结Fragment与FragmentPagerAdapter的生命周期及其关系
    Android的Touch事件分发机制简单探析
    个人项目开源之c++基于epoll实现高并发游戏盒子(服务端+客户端)源代码
    个人项目开源之Django文件中转站源代码
    个人项目开源之Django图书借阅系统源代码
    个人项目开源之实现矩形树图代码统计工具源代码
    颜色渐变算法
    echarts玩转图表之矩形树图
    解决MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk.问题
    引号有几种
  • 原文地址:https://www.cnblogs.com/tujia/p/13143703.html
Copyright © 2011-2022 走看看