Maison >développement back-end >Tutoriel Python >关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?

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

WBOY
WBOYoriginal
2016-06-06 16:22:351597parcourir

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

<span class="n">x</span><span class="o">=</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">]</span>
<span class="n">y</span><span class="o">=</span><span class="n">x</span>
<span class="n">y</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">=</span><span class="mi">4</span>
<span class="k">print</span> <span class="n">x</span>
<span class="o">>></span> <span class="n">x</span> <span class="o">=</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span><span class="p">]</span>

回复内容:

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

而Python中一切皆来源于此,而这两个宏定义为:
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?其实可发现PyObject_VAR_HEAD也只是PyObject_HEAD加上一个ob_size,于是Python中,每一个对象都拥有相同的对象头部,于是我们只需要用一个PyObject *就可以引用任意的一个对象,而不论该对象实际是一个什么对象,所以,当内存中存在某个Python对象时,该对象的开始的几个字节的含义一定会符合我们的预期,即PyObject_HEAD。而PyObject_HEAD宏定义中的_PyObject_HEAD_EXTRA其实只是指向_object的一个双向链表,
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?而ob_refcnt则是引用计数的计数器,而struct _typeobject *obtype则是类型,表示对象类型的类型对象:
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?
通过PyObject_VAR_HEAD可以发现类型其实也是一个对象(一切皆对象),而类型对象的类型则是类型对象所关联的类型:PyType_Type:
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?而即使如简单的int也是来填满这里的东西:
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思? 关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?于是,即使是int也是对象
所以即使你使用
i = 47
j = 47
也是对47的一个引用,而
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?
通过id,可以看出其在内存引用位置相同,而为什么相同?因为为了减少频繁调用开销,使用了small int对象池的技术:
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?于是只要超过257(包括257),则变了:
关于python中“赋值就是建立一个对象的引用”,大家怎么看?Python一切皆为对象又是什么意思?所以, 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中有些对象是可以在原处进行改变的(即可变对象),这种对象包括了列表、字典、集合和一些自定义的对象。而对于整数和字符串等不可变对象是不会存在题主所说的问题。比如:
<code class="language-python"><span class="o">>>></span> <span class="n">a</span> <span class="o">=</span> <span class="mi">123</span>
<span class="o">>>></span> <span class="n">b</span> <span class="o">=</span> <span class="n">a</span>
<span class="o">>>></span> <span class="n">a</span> <span class="o">=</span> <span class="mi">321</span>
<span class="o">>>></span> <span class="k">print</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span>
<span class="mi">321</span> <span class="mi">123</span>
</code>
问题的关键是,你写下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()
Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn