精华内容
下载资源
问答
  • python精讲 不可变对象可变对象

    千次阅读 2020-07-22 15:46:35
    文章目录对象可变对象与不可变对象可变对象可变对象 对象 Python 中的变量不是装有对象的“容器”,而是贴在对象上的“标签”。 真正的存贮位置是内存中 在python中,可变对象包括:list、set、dict、自定义对象...

    对象(object)

    cpu,内存,硬盘之间的关系:

    CPU与内存间的工作关系为:
    当我们在计算机上执行一个程序时,首先由输入设备向CPU发出操作指令,

    CPU接收到操作指令后,硬盘中对应的程序指令被直接加载到内存中,此

    后,CPU再对内存进行寻址操作,将加载到内存中的指令翻译出来,而后

    发送操作信号给操作控制器,实现程序的运行或数据的处理。

    对象

    • 对象即在内存中存储数据的一块区域
    • Python 中的变量不是装有对象的“容器”,而是贴在对象上的“标签”。
      真正的存贮位置是内存中
    - 每个对象都有三个要素:id(标识)(唯一性,每个对象都有唯一的id)
    					  type(类型)(决定对象的功能)
    					  value(值)(对象存储的数据值)
    

    对象

    • 在python中,可变对象包括:list、set、dict、自定义对象;
    • 不可对对象包括:int、float、str、bool、tuple等。
    • 不可变对象步允许自身内容进行修改。如果我们队一个不可变对象进行赋值,实际上是生成一个新对象,再让变量指向这个对象。哪怕这个对象简单到只是数字0和1

    每个对象在内存中都会存储三个数据:
    1.id(标识)
    2.type(类型)
    3.value(值)

    可变对象与不可变对象

    可变对象

    而可变对象即指在对象不改变的前提下让对象的数据发生改变
    即值发生改变但是 对象 未发生改变,例如 标识id 不会发生改变

    a = [1,2,3]
    print('修改前',a,id(a))
    a[0] = 4  #改变了值
    print('修改后',a,id(a))  #但是id未变
    
    修改前 [1, 2, 3] 1221617771648
    修改后 [4, 2, 3] 1221617771648
    

    对象没有发生改变而值发生改变
    a[0]=4

    重新赋值则开辟新的内存块存储新的值,顶替原来的对象和值
    在这里插入图片描述

    a = [1,2,3]
    print('修改前',a,id(a))
    a = [2,3,4]  #重新赋值即重新建立一个a,所以这个a不是原来的a,
                 #而是新生的a
    print('修改后',a,id(a))  #所以内存中重新开辟空间,对象发生改变
    
    修改前 [1, 2, 3] 2057897038528
    修改后 [2, 3, 4] 2057897038720
    

    因为对象不可变,所以为了提高效率,Python 会使用一些公用的对象:

    a = 1
    print('a', id(a))
    b = 1
    print('b', id(b))
    print(a == b)
    print(a is b)
    c = 'hello world'
    print('c', id(c))
    d = 'hello world'
    print('d', id(d))
    print(c == d)
    print(c is d)
    

    输出:

    a 4423761776
    b 4423761776
    True
    True
    c 4430180912
    d 4430180912
    True
    True
    

    这里顺便提一下 is 这个操作符。它和 == 的区别在于:== 只判断“值”是不是相等,而 is 则判断是否为同一个对象,也就是地址一致。比如:

    a = 2
    b = 2.0
    print(a == b)
    print(a is b)
    

    输出:

    True
    False
    

    不可变对象

    不可变对象不允许对自身内容进行修改。如果我们对一个不可变对象进行赋值,实际上是生成一个新对象,再让变量指向这个对象。:
    即重新赋值

    a = 0
    print('a', id(a))
    a = 1
    print('a', id(a))
    

    输出:

    a 4463151440
    a 4463151472
    

    在这里插入图片描述

    展开全文
  • java中可变对象与不可变对象

    千次阅读 2017-03-17 16:11:10
    可变对象(mutable Objects),不可变对象(Immutable ojbects),那么他们有什么区别呢? 不可变对象意味着这个对象是final的,对象中所有的公共属性是final的。同时说明这个对象是线程安全的,这意味着他们可以在多...

    可变对象(mutable Objects),不可变对象(Immutable ojbects),那么他们有什么区别呢?

    不可变对象意味着这个对象是final的,对象中所有的公共属性是final的。同时说明这个对象是线程安全的,这意味着他们可以在多线程中使用,而不需要使用synchronization。

    可变对象和不可变对象相反,java中大部分都是可变对象。


    不可变对象有哪些

    String,Integer以及其他的封装类型都是不可变对象。。


    怎样创建不可变对象

    类是final的,并且中所有类属性都是final的。

    public final class FinalTest {
        private final String NAME = "name";
        private final String AGE  = "age";
    
        public String getNAME() {
            return NAME;
        }
    
        public String getAGE() {
            return AGE;
        }
    }



    展开全文
  • JAVA - 可变对象与不可变对象

    千次阅读 2018-06-14 18:34:08
    可变对象在并发程序中比较有用,由于其状态无法改变,因此无法被线程的干扰损坏或者被视为不一致状态。基本概念 *不可变对象(Immutable Objects)即对象一旦被创建它的状态(对象的数据,也即对象属性值)就不能...

    不可变对象在并发程序中比较有用,由于其状态无法改变,因此无法被线程的干扰损坏或者被视为不一致状态。

    基本概念   

    *不可变对象(Immutable Objects)即对象一旦被创建它的状态(对象的数据,也即对象属性值)就不能改变,任何对它的改变都应该产生一个新的对象

    * 可变对象(Mutable Objects):相对于不可变类,可变类创建实例后可以改变其成员变量值,开发中创建的大部分类都属于可变类

    * 不可变对象的类即为不可变类(Immutable Class)。JAVA平台类库中包含许多不可变类,如String、基本类型的包装类、BigInteger和BigDecimal等。

    编写不可变类

    可以遵照以下几点来编写一个不可变类:

    A. 确保类不能被继承将类声明为final, 或者使用静态工厂并声明构造器为private。如果类可以被继承会破坏类的不可变性机制,只要继承类覆盖父类的方法并且继承类可以改变成员变量值,那么一旦子类以父类的形式出现时,不能保证当前类是否可变。

    B. 使用private和final修饰符来修饰该类的属性

    注:如果成员属性为变对象属性,不要使这些对象改变:

    1)不要提供更改可变对象的方法

    2)不要共享对可变对象的引用,不要存储传给构造器的外部可变对象的引用。因为引用可变对象的成员变量和外部可变对象的引用指向同一块内存地址,用户可以在不可变类之外通过修改可变对象的值

    public final class ImmutableDemo {  
        private final int[] myArray;  
        public ImmutableDemo(int[] array) {  
            this.myArray = array; // wrong  
        }  
    }

    为了保证内部的值不被修改,可以采用深度拷贝的方法来复制一个对象并传入副本的引用来确保类的不可变

    public final class MyImmutableDemo {  
        private final int[] myArray;  
        public MyImmutableDemo(int[] array) {  
            this.myArray = array.clone();   
        }   
    }

    有必要时类中的方法返回内部可变对象的副本而不是原对象

    C. 不要提供任何可以修改对象状态的方法不仅仅是set方法, 还有任何其它可以改变状态的方法

    举个例子:

    import java.util.Date;
    
    public final class Planet {
        //声明为final的基本类型数据总是不可变的
        private final double fMass;
        //不可变的对象属性 (String对象不可变)
        private final String fName;
        //可变对象的属性,因为可变属性只能被这个类改变,采用深度拷贝的方法来复制一个对象并传入副本的引用
        private final Date fDateOfDiscovery;
        
        public Planet(double aMass, String aName, Date aDateOfDiscovery) {
            fMass = aMass;
            fName = aName;
            //创建aDateOfDiscovery的一个私有拷贝
            //这是保持fDateOfDiscovery属性为private的唯一方式, 并且保护这个
            //类不受调用者对于原始aDateOfDiscovery对象所做任何改变的影响
            fDateOfDiscovery = new Date(aDateOfDiscovery.getTime());
        }
        //返回一个基本类型值.
        public double getMass() {
            return fMass;
        }
        //调用者得到内部属性的一个直接引用. 由于String是不可变的所以没什么影响
        public String getName() {
            return fName;
        }
        //返回一个可变对象的一个保护性拷贝.调用者可以任意改变返回的Date对象,但是不会
        //影响类的内部.为什么? 因为它们没有fDate的一个引用. 更准确的说, 它们
        //使用的是和fDate有着相同数据的另一个Date对象
        public Date getDateOfDiscovery() {
            return new Date(fDateOfDiscovery.getTime());
        }
    
        public static void main(String[] args) {
        	Planet planet = new Planet(1.0D, "earth", new Date());
        	Date date = planet.getDateOfDiscovery();
        	date.setTime(111111111L);
        	System.out.println("the value of fDateOfDiscovery of internal class : " + planet.fDateOfDiscovery.getTime());
        	System.out.println("the value of date after change its value : " + date.getTime());
    	}
    }

    运行结果:

    the value of fDateOfDiscovery of internal class : 1393943752205
    the value of date after change its value : 111111111

    不可变对象的优缺点

    优点

    * 构造、测试和使用都很简单

    * 不可变对象是线程安全的,在线程之间可以相互共享,不需要利用特殊机制来保证同步问题,因为对象的值无法改变。可以降低并发错误的可能性,因为不需要用一些锁机制等保证内存一致性问题也减少了同步开销。

    * 不可变对象可以被重复使用,可以将它们缓存起来重复使用,就像字符串字面量和整型数字一样。可以使用静态工厂方法来提供类似于valueOf()这样的方法,它可以从缓存中返回一个已经存在的Immutable对象,而不是重新创建一个。

    public class CacheImmutale {  
        private final String name;  
        private static CacheImmutale[] cache = new CacheImmutale[10];  
        private static int pos = 0;  
      
        public CacheImmutale(String name) {  
            super();  
            this.name = name;  
        }  
      
        public String getName() {  
            return name;  
        }  
      
        public static CacheImmutale valueOf(String name) {  
            // 遍历已缓存的对象  
            for (int i = 0; i < pos; i++) {  
                // 如果已有相同实例,直接返回该缓存的实例  
                if (cache[i] != null && cache[i].getName().equals(name)) {  
                    return cache[i];  
                }  
            }  
            // 如果缓冲池已满  
            if (pos == 10) {  
                // 把缓存的第一个对象覆盖  
                cache[0] = new CacheImmutale(name);  
                pos = 1;  
                return cache[0];  
            } else {  
                // 把新创建的对象缓存起来,pos加1  
                cache[pos++] = new CacheImmutale(name);  
                return cache[pos - 1];  
            }  
        }  
      
        @Override  
        public int hashCode() {  
            return name.hashCode();  
        }  
      
        @Override  
        public boolean equals(Object obj) {  
            if (obj instanceof CacheImmutale) {  
                CacheImmutale ci = (CacheImmutale) obj;  
                if (name.equals(ci.getName())) {  
                    return true;  
                }  
            }  
            return false;  
        }  
      
        public static void main(String[] args) {  
            CacheImmutale c1 = CacheImmutale.valueOf("hello");  
            CacheImmutale c2 = CacheImmutale.valueOf("hello");  
            System.out.println(c1 == c2);// 输出结果为true  
        }  
    }

    缺点:

    * 不可变对象最大的缺点就是创建对象的开销,因为每一步操作都会产生一个新的对象,制造大量垃圾,由于他们不能被重用而且对于它们的使用就是”用“然后”扔“,会创造很多的垃圾,给垃圾收集带来很大的麻烦

    展开全文
  • Python中的可变对象和不可变对象

    千次阅读 2017-12-11 10:25:31
    Python在heap中分配的对象分成两类:可变对象和不可变对象。所谓可变对象是指,对象的内容是可变的,例如list。而不可变的对象则相反,表示其内容不可变。不可变对象:int,string,float,tuple 可变对象 :l

    python变量赋值(可变与不可变)

    知识点:python中,万物皆对象。
         python中不存在所谓的传值调用,一切传递的都是对象的引用,也可以认为是传址。
    Python在heap中分配的对象分成两类:可变对象和不可变对象。所谓可变对象是指,对象的内容是可变的,例如list。而不可变的对象则相反,表示其内容不可变。

    不可变对象:int,string,float,tuple
    可变对象 :list,dictionary
    一、不可变对象

    由于Python中的变量存放的是对象引用,所以对于不可变对象而言,尽管对象本身不可变,但变量的对象引用是可变的。运用这样的机制,有时候会让人产生糊涂,似乎可变对象变化了。如下面的代码:

    i=73
    i=i+2
    不可变对象不变,引用变了
    这里写图片描述

    不可变的对象的特征没有变,依然是不可变对象,变的只是创建了新对象,改变了变量的对象引用。
    看看下面的代码,更能体现这点的。

    print(id(100)) # 1362346144
    a = 100
    print(id(a)) # 1362346144
    b = 100
    print(id(b)) # 1362346144
    但如果变成258则id就有变化

    print(id(258)) # 1659053321968
    a = 258
    print(id(a)) # 1659053321968
    b = 258
    print(id(b)) # 1659053319280
    为何不一样了?

    (答案转自知乎问题:为什么Python有相同的不可变对象id不同?或者知乎原答案)

    二、可变对象
    这里写图片描述
    其对象的内容是可以变化的。当对象的内容发生变化时,变量的对象引用是不会变化的。

    关于此问题的大坑:函数默认参数的使用
    先定义一个函数,传入一个list,添加一个END再返回:
    def add_end(L=[]):
    L.append(‘END’)
    return L
    当你正常调用时,结果似乎不错:

    >>> add_end([1, 2, 3])
    [1, 2, 3, 'END']
    >>> add_end(['x', 'y', 'z'])
    ['x', 'y', 'z', 'END']

    当你使用默认参数调用时,一开始结果也是对的:

    >>> add_end()
    ['END']

    但是,再次调用add_end()时,结果就不对了:

    >>> add_end()
    ['END', 'END']
    >>> add_end()
    ['END', 'END', 'END']

    很多初学者很疑惑,默认参数是[],但是函数似乎每次都“记住了”上次添加了’END’后的list。
    原因解释如下:
    Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。
    所以,定义默认参数要牢记一点:默认参数必须指向不变对象!
    要修改上面的例子,我们可以用None这个不变对象来实现:

    def add_end(L=None):
        if L is None:
            L = []
        L.append('END')
        return L

    现在,无论调用多少次,都不会有问题:

    >>> add_end()
    ['END']
    >>> add_end()
    ['END']

    为什么要设计str、None这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。

    作者:五秋木
    链接:http://www.jianshu.com/p/b690422ec02a
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    展开全文
  • 可变对象 vs 不可变对象(Python)

    千次阅读 2016-08-27 22:27:57
    Python 在 heap 中分配的对象分成两类:可变对象和不可变对象。所谓可变对象是指,对象的内容是可变的,例如 list。而不可变的对象则相反,表示其内容不可变。 不可变对象:int,string,float,tuple 可变对象 :...
  • (转)Java 可变对象和不可变对象

    千次阅读 2018-07-23 15:44:18
     不可变对象(Immutable Objects)即对象一旦被创建它的状态(对象的数据,也即对象属性值)就不能改变,反之即为可变对象(Mutable Objects)。  不可变对象的类即为不可变类(Immutable Class)。Java平台类库中包含...
  • Python中可变对象和不可变对象

    千次阅读 2017-02-13 12:56:21
    之前写了FPGrowth的代码,写得非常恶心,觉得和C语言、C++的工程文件很不相同。其中就有关于传引用、传值的疑问。截一段Leetcode的代码这题好像是Leetcode ...经过查看资料我就知道这和命名域以及可变对象和不可变对象
  • java 中不可变对象

    千次阅读 2018-11-30 23:12:07
    java 中不可变对象 本文我们说明什么是不可变对象,在java 中如何实现以及其有和好处。 1. 什么是不可变对象可变对象是指对象被创建之后,其内部状态保存不变的对象。这意味着其公开的API保证在对象的整个生命...
  • python中的可变对象与不可变对象

    千次阅读 2018-12-20 22:40:20
    python与C/C++不一样,它的变量使用有自己的特点,...下面本文将对python里面的“可变数据类型”和“不可变数据类型”进行分析。 首先,我们需要知道在python中哪些是可变数据类型,哪些是不可变数据类型。可变数据...
  • 可变对象与不可变对象

    万次阅读 2018-08-12 22:22:48
     好了,现在开始讲本文的主题–可变对象和不可变对象,在python中,可变对象包括:list、set、dict、自定义对象,不可对对象包括:int、float、str、bool、tuple等。不可变对象步允许自身内容进行修改。如果我们队...
  • python的可变和不可变对象

    千次阅读 2016-04-29 14:59:36
    python的对象分为可变对象(mutable)和不可变对象(immutable) 不可变对象(immutable)包括:常数、字符串、元组和不可变集合(frozensets) 可变对象包括:列表、字典、自定义类对象(也可用特殊方法定义为不可变类) ...
  • 文章目录四个线程安全策略不可变对象定义不可变对象需要满足的条件如何创建不可变对象使用final关键字定义不可变对象修饰变量示例final 修饰基本数据类型及String: 初始化之后不能修改 (线程安全)final修饰引用...
  • 深入理解Java中的不可变对象

    千次阅读 2020-03-20 10:49:23
    二哥,你能给我说说为什么 String 是 immutable 类(不可变对象)吗?我想研究它,想知道为什么它就不可变了,这种强烈的愿望就像想研究浩瀚的星空一样。但无奈自身功力有限,始终觉得雾里看花终隔一层。二哥你的...
  • python中有可变对象和不可变对象可变对象:list,dict.不可变对象有:int,string,float,tuple.最近看到这些知识下面来整理一下... python不可变对象int,string,float,tuple先来看一个例子 def int_test(): i = 77...
  • Java不可变对象

    千次阅读 2016-01-10 16:27:28
    可变对象是指一个对象的状态在对象被创建之后就不再变化。不可变对象对于缓存是非常好的选择,因为你不需要担心它的值会被更改。 创建一个不可变类: 将类声明为final,所以它不能被继承;将所有的成员声明...
  • 从简,不说废话: # 数字、字符串、tuple都是不可变对象 # list、dict是可变对象 ...原因在于:可变对象,参数改变的是可变对象,其内容可以被修改。不可变对象,改变的是函数内变量的指向对象。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,083,905
精华内容 433,562
关键字:

可变对象