• 技术文章 >后端开发 >Python教程

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

    2016-06-06 16:22:35原创737
    为什么我觉得好不方便啊......
    比如如下的代码:

    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的一个双向链表,
    而ob_refcnt则是引用计数的计数器,而struct _typeobject *obtype则是类型,表示对象类型的类型对象:

    通过PyObject_VAR_HEAD可以发现类型其实也是一个对象(一切皆对象),而类型对象的类型则是类型对象所关联的类型:PyType_Type:
    而即使如简单的int也是来填满这里的东西:
    于是,即使是int也是对象
    所以即使你使用
    i = 47
    j = 47
    也是对47的一个引用,而

    通过id,可以看出其在内存引用位置相同,而为什么相同?因为为了减少频繁调用开销,使用了small int对象池的技术:
    于是只要超过257(包括257),则变了:
    所以, 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()
    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:print gt
    上一篇:Meta Programming 主要解决什么了问题? 下一篇:用 python 写的爬虫,有哪些提高的技能?
    VIP课程(WEB全栈开发)

    相关文章推荐

    • 【腾讯云】年中优惠,「专享618元」优惠券!• Python接口自动化测试必备基础之http协议详解• Python 3.11中的最佳新功能和功能修复• 实例详解Python面向对象的四大特征• Python数据分析之concat与merge函数(实例详解)• 一起聊聊Python的编码样式
    1/1

    PHP中文网