作为一个由c/c++转过来的菜鸟,刚接触Python的变量的时候很不适应,应为他的行为很像指针,void* ,不知道大家有没有这样的感觉。其实Python是以数据为本,变量可以理解为标签。作为c/c++的菜鸟,把跟踪变量地址的习惯带入Python,举个小例子说明Python的变量,对象,及参数传递。

 '''例子1'''
x = 1
def fun(x):
x = 2
return None fun(x)
print(x)

其实不打印也可以,我们用pycharm单步调试,看一下在每一行执行中,变量x的值的变化,及其地址的变化(其实这句话应该改成:变量x的指向变化更准确)

Python中id()函数,可以返回对象的地址,id()的官方解释是:Return the “identity” of an object,既然是identity,肯定是唯一的;官方又说:CPython implementation detail: This is the address of the object in memory。我们暂时把id()返回值看做是对象在内存中的地址。

第一步:进入debug,在监视窗口,添加对Id(x),和id(y) 的观察,蓝色高亮,表示下一步将执行,我们看到这时,x,y都没有分配地址

第二步:执行下一步,我们发现变量x,开始分配地址, 1392686144,我们记下这个数。

第三步:进入函数中,执行 x = 2语句,我们发现,x的地址已经变成 1392686176,这就是Python 变量的特性,我们不能理解成把变量x赋值为2,而是“名字为x的标签指向对象2”,这样更准确。

第四步:返回fun(x)函数,我们发现X的id()值又变回原来的数字,在这个例子中,我们把局部变量和全局变量用同一个标签指示,当调用函数,进入函数内部执行时,系统会创建堆栈,保留进入函数前的运行环境及数据。进入函数后,有创建了一个同名的标签x,x = 2,把局部标签指向局部对象2,这是局部标签x指向一个新的对象,内存地址肯定变化,当return none,返回函数调用时,堆栈撤销,局部的对象,变量随之撤销,局部标签x也撤销,此时x做回自己,变成全局标签x,依旧指向数字对象1.这就是为什么在函数内部,标签x指向其他对象后,返回调用,又恢复调用前的内存地址。

第一个例子中,从标签x的内存地址变化,帮我们理解Python的变量的行为。

在第二个例子中,我们仍然通过监视标签的内存地址变化,理解参数传递的过程

 '''例子2'''
a = []
def fun(a):
a.append(1)
return None fun(a)
print(a)

第一步:执行完函数调用,参数赋值,蓝色高亮是下一步将要执行的代码。我们发现在这一步,发生了参数赋值,创建堆栈,局部标签x的内存地址与外部标签a的内存地址相同,说明这一步,完成参数赋值,我们是不是可以把Python的“赋值语句”理解为“标签指向”这个动作?从这看,这样理解是可以的。所以“参数赋值”这个动作,可以理解为统一标签指向。

第二步: 当函数返回时,我们发现列表a的地址没有改变,并且列表中元素1得到保留,没有因为局部变量撤销而消失,这回一个典型的通过标签(引用),在局部过程中改变全局变量的例子。Python标签的这种特性是不是很像c++中的引用?是不是很像c中的指针?

总结:Python的变量,我们用标签来理解,参考c的void*,参考c++中的&,Python的赋值动作,可以理解为“标签改变指向”的动作。参数传递过程,是交换标签指向的过程

python的变量,对象的内存地址以及参数传递过程的更多相关文章

  1. 一个对象toString()方法如果没有被重写,那么默认调用它的父类Object的toString()方法,而Object的toString()方法是打印该对象的hashCode,一般hashCode就是此对象的内存地址

    昨天因为要从JFrame控件获取密码,注意到一个问题,那就是用toString方法得到的不一定是你想要的,如下: jPasswordField是JFrame中的密码输入框,如果用下面的方法是得不到密码 ...

  2. JVM运行时数据区及对象在内存中初始化的过程

    JVM运行时数据区 Java虚拟机所管理的内存区域,也称为运行时数据区,分为以下几个运行时数据区,如图所示 程序计数器:当前程序所执行字节码的行号指示器 程序计数器(Program Counter R ...

  3. python中的函数对象的内存地址是多少

    今天和同学讨论一个问题,发现了函数的内存地址和我想象的不一样. 我以为同一个函数,假如给的参数不一样,那么这两个函数的id就不一样. 然后经过实验,发现python为了便于管理函数,所有的函数都放在同 ...

  4. Python中类和对象在内存中是如何保存?

    类以及类中的方法在内存中只有一份,而根据类创建的每一个对象都在内存中需要存一份,大致如下图: 如上图所示,根据类创建对象时,对象中除了封装 name 和 age 的值之外,还会保存一个类对象指针,该值 ...

  5. 在python里使用WriteProcessMemory修改内存地址上的值

    import os import sys from ctypes import * windll.kernel32.WriteProcessMemory.argtypes = [c_void_p, c ...

  6. python如何从内存地址上加载pythn对象

    python如何从内存地址上加载pythn对象 在python中我们可以通过id函数来获取某个python对象的内存地址,或者可以通过调用对象的__repr__魔术函数来获取对象的详细信息 def t ...

  7. (内存地址hashcode与对象内容hashcode)分析== 和 equal()方法

    ==.equals()和hashCode()字符串测试 1.hashCode() 是根据 内容 来产生hash值的 2.System.identityHashCode() 是根据 内存地址 来产生ha ...

  8. python获取内存地址上存储的值

    在python中,可以通过id()这个方法来获取对象的内存地址. 但是反过来,怎么获取内存地址上存储的值? 先看一段代码: from ctypes import string_at from sys ...

  9. 优雅的重载toString方法,打印对象内容而不是打印内存地址的方法

    如果直接在日志或者System.out.println中打印java对象,会打印这个对象的内存地址,而不是具体内容. 为了便于调试,一般的做法有2种: 1.重写toStrong方法 2.将对象传入JS ...

随机推荐

  1. URL地址中的字符串转换

    url出现了有+,空格,/,?,%,#,&,=等特殊符号的时候,可能在服务器端无法获得正确的参数值,怎么解决?解决办法将这些字符转化成服务器可以识别的字符,对应关系如下:URL字符转义 用其它 ...

  2. mac配置python自然语言处理环境

    一.nltk安装 Ⅰ.工具安装步骤 1.根据python版本从 https://pypi.python.org/pypi/setuptools 下载对应版本的setuptools.然后,在终端下运行, ...

  3. git学习------> Gitlab如何进行备份恢复与迁移?

    前段时间,在某台CenterOS服务器上搭建了Gitlab环境,并且大家陆陆续续的都把代码从svn迁移到了gitlab,但是之前的CenterOS服务器并不是搭建在公司的机房环境,而是搭建在办公室的某 ...

  4. maya布料预设解析

    今天做了一天布料.数值都是自己在那调整.结果发现maya自带预设,基本有些都不用调整,直接预设,效果非常不错.累死累活半天. 下来看看  预设 解析吧 ncloth新布料系统是 Maya 8.0 后新 ...

  5. java7(3)——增强的catch之自动释放资源

    跟mutilcatch一样,java7提供了自动释放资源的方法,但还是很少看到人使用,估计是麻烦去重写close方法.不过jdk内部一些类已经改成使用增强的catch来释放资源的写法,所以我们有必要了 ...

  6. GROUP BY 和 ORDER BY一起使用

    转:http://lzfhope.blog.163.com/blog/static/636399220092554045196/ 环境:oracle 10g单单group by 或者order by本 ...

  7. spring MVC学习(二)---配置相关的东西

    1.在上一节中我们提到过每一个DispatcherServlet都会有一个上下文 (WebApplictionContext),并且继承了这些上下文中的bean,其中以一些"特殊" ...

  8. 浅谈Spark2.x中的Structured Streaming

    在Spark2.x中,Spark Streaming获得了比较全面的升级,称为Structured Streaming,和之前的很不同,功能更强大,效率更高,跟其他的组件整合性也更好. 连续应用程序c ...

  9. intellij idea 重命名或复制一个项目(不用重启)

    Idea 内无法直接修改Explorer 里文件夹的名称,只能手动改文件夹的名称. 目前找到的最好的方法: 1)重命名一个项目 在Idea 项目关闭状态下,在 Explorer (Windows) / ...

  10. CentOS忘记用户名或者密码解决办法

    方法一:如果用户名和密码都忘记了,可以用以下这个方法找回:(和第二种大步骤差不多,需注意3,4步) 1. 在出现grub画面时,用上下键选中你平时启动linux的那一项,然后按e键 2. 再次用上下键 ...