Python中的变量 内存模型

引用语义

python中的变量采用引用语义,每一个变量名其实存储的是实际存放数据的内存的地址,如下图:

  另外,在python中对变量名的访问(例如x=10),可以理解为通过只读的指针(地址)访问存放数据的内存空间,我们通过变量中存放的地址访问内存只能读,不能写,写的话将导致重新分配一块内存空间,存放新数据,并将变量中存放的原有的地址替换成新地址。下面我们分析一段代码:

x = 15
y = 15
s = [15, 20]
def func():		#c语言表达
    x = 10  	        #addr_x = new int; *addr_x = 10
	
    global y
    y = 10		#*addr_y = 10
	
    s[0] = 10           #*(*(addr_s)+0) = 10

对应的内存分布如下:

 

青涩难懂的解释1:

毫无疑问在python中对象也是一块内存,内存中除了包含属性、方法之外,还包含了对象得类型,我们通过引用来访问对象,比如a=A(),首先python创建一个对象A,然后声明一个变量a,再将变量a与对象A联系起来。变量a是没有类型的,它的类型取决于其关联的对象。a=A()时,a是一个A类型的引用,我们可以说a是A类型的,如果再将a赋值3,a=3,此时a就是一个整型的引用,但python并不是弱类型语言,在python中'2'+3会报错,而在php中'2'+3会得到5。可以这么理解,在python中变量类似于c中的指针,和c不同的是python中的变量可以指向任何类型,虽然这么说不太准确,但是理解起来容易点。

青涩难懂的解释2:

我们可以使用C#中的一些概念来类比python中的变量模型:

首先解释一下C#的机制:c#就相当于将c语言中的指针和非指针强行分开,程序员将不能决定使用的类型的形式,如果使用类对象,只能使用引用的形式,如果使用结构体和简单类型,只能使用值类型,不像在C++中我们完全可以在栈上定义对象,并使用非指针的形式操作对象,也完全可以在堆上分配int,并以指针的形式访问int。

C#中所有的对象都分为引用类型和值类型,它们最主要的区别是,对值类型来说,变量内存处存放的即是数据,引用类型的变量内存处存放的是真正数据对应的地址,两个值类型相互赋值,传递的是数据(和c语言一致),赋值之后它们将完全独立;两个引用类型的变量赋值(类似于C语言中指针赋值),传递的是地址,它们将指向同一块堆空间,对一个引用变量操作后,另一个引用变量所对应的数据将同步改变,那么在python中,我们可以理解为所有的变量全部都是引用类型,并且Python中也分只读的类型(例如字符串、元组、数值等)和非只读的类型(例如列表、字典等),只读的引用类型和C#中的string类型一致,非只读的和C#中的非只读变量一致。严格来说,python中没有像C#中的值类型,只有只读的引用类型,只读的引用类型表现出来的性质和值类型很像,但实现方案却不同。

string类型在C#中是只读的引用类型,string s1 = "ni hao "; string s2 = s1; s1 = s1 + "ma?"; 结果是s1 = "ni hao ma?", s2 = "ni hao"; 对s1的操作并没有影响到s2,因为,对s1进行赋值操作将导致s1执行新的内存空间"ni hao ma?",并不是对原来的内存空间"ni hao"进行修改,python中的只读类型变量也是这样,对一个变量进行赋值操作,将导致此变量指向新的内存空间,而不是修改老的内存空间。

其实C#中的string类型这一特性是非常容易实现的,只需要重载"="运算符时返回一个新的对象出去,而不是修改老的对象然后返回,然后string类型中所有的成员函数都禁止修改string类型的内容,涉及到表面上好像修改了内容的成员函数其实都是构造了一个新的string对象(包含着我们所期望的内容)。当然具体的实现方案并没有深入了解,此处只是猜测。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值