python有指针概念吗,python打印类的方法
最近在学习C,打印问题的时候,遇到了关于引用和指针的问题。在重申了相关知识后,发现C中的引用和python中的有很大不同。我想这也是C比python效率高很多的原因之一。两篇文章,我想梳理一下python和C在引用上的区别,以及C在引用和指针上的区别。
引用Python
python中的引用是引用赋值,和浅拷贝一样。例如:
在[13]中:a=1
在[14]中:b=a
在[15]中:id(a))
Out[15]: 4553065616
在[16]中:id(b))
Out[16]: 4553065616
在[20]中:b是a
Out [20]:真
在[21]中:b==a
Out [21]:真
在上面的代码中,不需要声明变量类型,所以先初始化值为1、名称为A的变量。其实python是没有变量的。正确的是标签。然后变量B引用标签A,此时标签B的值等于标签A的值,内存地址相同。
但是,python中还有一个引用的特性。您可以更改APP应用程序
在[23]中:b=2
在[24]中:id(b))
Out[24]: 4553065648
在[25]中
Out[25]: 1
在[26]:id(a))
Out[26]: 4553065616
-
在[24]中:b=b 1
在[25]: b
Out[25]: 2
在[26]中
Out[26]: 1
在[27]:id(a))
Out[27]: 4369581200
在[28]中:id(b))
Out[28]: 4369581232
此时变量B并没有引用变量A,而是引用了名为2的int数据,内存地址也不再与A相同,回头看A发现A并没有受到B的影响,更具体的说,这是因为在python中,int数据类型是不可变的,所以引用变量B后A的值或者内存是不变的,也就是说int是线程安全的数据类型。
刷卡机
python引用和C最大的区别在于,C的引用一旦赋值,引用对象就不能更改,后续的赋值操作只能修改引用对象本身。
另一方面,python是不同的。没有这个概念。替换引用后,标签将贴在最新的对象上。
可变类型数据
接下来,让我们看看python中对可变数据的引用。
在[1]中:a=[ 1,2,3 ]
在[2]中:b=a
在[4]中:b .附加(4).
在[5]中
输出[5] : [ 1,2,3,4 ]
在[6]中:id(b))
Out[6]: 4415640192
在[7]中:id(a))
Out[7]: 4415640192
在[8]中
输出[8] : [ 1,2,3,4 ]
对于变量类型的数据,标签B首先指的是标签A引用的对象,此时如果操作标签B改变数据,可以看到标签A引用的对象也发生了变化。
当改变变量类型的数据时,操作本身将成为引用对象。所以无论A还是B发生变化,都会影响到对象的其他引用。
当变量类型数据被重新分配时
在[ 12 ]中:a=[ 1,2,3 ]
在[13]中:b=a
在[ 14 ]中:b=[ 2,3,4 ]
在[15]中
输出[ 15 ] : [ 1,2,3 ]
在[16]中:id(a))
Out[16]: 4406584576
在[17]中:id(b))
Out[17]: 4406530608
这时候和不可变类型是一样的情况。标签B再次引用新对象,向a告别。
我们来看一个比较典型的例子。
发生这种情况是因为更改可变数据实际上是更改引用。
[ 37 ] 3360 a=[ 1,2,3 ]
在[38]中:a[1]=a
在[39]中
Out[39]: [1,[。],3]
我修改了操作,让a[1]指向标签a引用的对象,我以为结果是[1,[1,2,3],3],但是修改操作只会修改引用对象本身,在列表[1,3]中?a指了指自己,引起了一个循环。
要避免这种情况,可以通过复制来解决这个问题。
在[ 41 ]中:a=[ 1,2,3 ]
In [42]: a[1]=copy.copy(a(
在[43]中
Out[43]: [1,[1,2,3],3]
浅拷贝
对于不可变类型,编写副本与赋值是一样的
在[49]中:a=1
在[50]中:b=copy.copy(a))
在[51]: b
Out[51]: 1
在[52]3360id(a)中)
Out[52]: 4369581200
在[53]3360id(b)中.
Out[53]: 4369581200
标签B和标签A都引用这个数据。
看看造成上述循环的问题。复制到这里就可以解决了。
在[1]中:a=[ 1,2,3 ]
在[2]中:a[1]=a[:]
在[3]中
输出[3]: [1,[1,2,3],3]
在此示例中,您将使用切片作为复制操作,并将由引用的对象的第二个元素指向复制的新对象。
复印缺陷分析
有一天无意中发现了薄抄的缺点,很有意思。
在[31]中:a=[1,[ 2,3 ],4]
在[32]中:b=a[:]
在[33]3360id(a[1])
Out[33]: 4436979376
在[34]中:id(b[1])
Out[34]: 4436979376
在[40]中:a[1][1]=2
在[41]中
Out[41]: [1,[ 2,2 ],4]
在[42]中
Out[42]: [1,[ 2,2],4]
首先,如果变量数据被轻微复制,编译器将重新打开内存来保存新对象。也就是说,复制了变量数据的新对象不同于原始对象。但是,在上面的例子中,如果不变数据作为不变数据对象的元素存在,那么副本就将其作为不变对象对待,所以可以看出,上面的a[1]和b[1]的内存地址是相同的。
必须用深度复制来解决这个问题。
深度复制
在[43]中:a=[1,[ 2,3],4]
在[44]中:b=copy.deepcopy(a))
在[45]中:a[1][1]=2
在[46]中
Out[46]: [1,[ 2,2 ],4]
在[47]中
Out[47]: [1,[ 2,3 ],4]
通过深度复制为嵌套元素创建新内存。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。