关于python中“赋值就是建立一个对象的引用”,大家怎么看?python一切皆为对象又是什么意思?

为什么我觉得好不方便啊……比如如下的代码:

x=[1,2,3,4]
y=x
y[0]=4
print x
>> x = [4 2 3 4]
回复内容:
挺方便的object.h而python中一切皆来源于此,而这两个宏定义为:其实可发现pyobject_var_head也只是pyobject_head加上一个ob_size,于是python中,每一个对象都拥有相同的对象头部,于是我们只需要用一个pyobject *就可以引用任意的一个对象,而不论该对象实际是一个什么对象,所以,当内存中存在某个python对象时,该对象的开始的几个字节的含义一定会符合我们的预期,即pyobject_head。而pyobject_head宏定义中的_pyobject_head_extra其实只是指向_object的一个双向链表,其实可发现pyobject_var_head也只是pyobject_head加上一个ob_size,于是python中,每一个对象都拥有相同的对象头部,于是我们只需要用一个pyobject *就可以引用任意的一个对象,而不论该对象实际是一个什么对象,所以,当内存中存在某个python对象时,该对象的开始的几个字节的含义一定会符合我们的预期,即pyobject_head。而pyobject_head宏定义中的_pyobject_head_extra其实只是指向_object的一个双向链表,而ob_refcnt则是引用计数的计数器,而struct _typeobject *obtype则是类型,表示对象类型的类型对象:而ob_refcnt则是引用计数的计数器,而struct _typeobject *obtype则是类型,表示对象类型的类型对象:通过pyobject_var_head可以发现类型其实也是一个对象(一切皆对象),而类型对象的类型则是类型对象所关联的类型:pytype_type:而即使如简单的int也是来填满这里的东西:而即使如简单的int也是来填满这里的东西:于是,即使是int也是对象于是,即使是int也是对象所以即使你使用 i = 47j = 47也是对47的一个引用,而通过id,可以看出其在内存引用位置相同,而为什么相同?因为为了减少频繁调用开销,使用了small int对象池的技术:于是只要超过257(包括257),则变了:于是只要超过257(包括257),则变了:所以, m,n虽然都是对258对象的引用,却是不同的内存地址了.所以, m,n虽然都是对258对象的引用,却是不同的内存地址了.剩下的你就可以继续按照这条路线探寻python的机制了,而你的问题也基本得到解答了,当你疑惑一些问题时,源码是最好的解释。 :-)p.s. python版本: 2.7.8
变量一般有三种风格:引用式:变量是对象的名字,在运行时可以绑定到任意对象上,比如python。值式:变量是存储位置的名字,在编译时绑定已经完成,运行时不可以改变,比如c。混合式:某些类型是值式的,某些类型是引用式的,比如c#的struct和class。c++比较特殊,基本上可以说是值式的,但是由于有别名存在,所以也有些引用式的特点。引用式和值式的区别就是在赋值操作上,引用式的赋值是变量名的重新绑定,而值式的赋值是对象的拷贝。他们两者是可以互相模拟的。引用式的想要有值式的赋值,只需要显式的拷贝或者copy-on-write就可以了。而值式的想要有引用式的赋值只需要使用指针就可以了。你可能只是习惯了c/c++的值式的风格,还没适应引用式的风格。看起来可能风格统一比较好。但是实际用起来我觉得c#的混合式是最好用的。
其实现在大部分的语言都是这样的:对象以引用的方式提供给编程者,对象赋值只是多个变量指向同一个对象。大概只有c/c++的赋值是真的拷贝一份。
a = 258在python看来就是:创建一个pyintobject对象,值为258;a是一个指向pyobject的指针,将a指向此pyintobject对象之所以能这么干就和 @蓝色的答案解释的一样,所有的pyobject都有同样的头部。
在python中有些对象是可以在原处进行改变的(即可变对象),这种对象包括了列表、字典、集合和一些自定义的对象。而对于整数和字符串等不可变对象是不会存在题主所说的问题。比如:

>>> a = 123
>>> b = a
>>> a = 321
>>> print a, b
321 123

问题的关键是,你写下y=x时,其实并没有新建一个y,而是一个类似c++中引用的机制,具体可以这样看:>>> x = [1,2,3,4]>>> y = x>>> id(x)43246536l>>> id(y)43246536l所以x和y其实是一个东西。如果要复制一个list,需要使用>>> y = list(x)或者>>> y = x[:]
你加上“指针”一起理解。
你想深拷贝就用y=x[:]。其实也没啥不好的,py的对象分为可变和不可变两种,只要理解了这一点一切都很清晰。
id()

Posted in 未分类

发表评论