作为一个由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. 如何使文本溢出边界不换行强制在一行内显示?#test{width:150px;white-space:nowrap;}

    #test{width:150px;white-space:nowrap;}

  2. Purpose of ContextLoaderListener in Spring

    The ApplicationContext is where your Spring beans live. The purpose of the ContextLoaderListener is ...

  3. TensorFlow学习笔记(四)图像识别与卷积神经网络

    一.卷积神经网络简介 卷积神经网络(Convolutional Neural Network,CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现. ...

  4. C++关联式容器的排序准则

    stl中set和map为关联式容器,会根据排序准将元素自动排序.原型如下: template<class _Kty, class _Pr = less<_Kty>, class _A ...

  5. Mac Outlook邮箱MicrosoftExchange邮箱快满了,请减小邮箱大小。

    这两天我的Mac电脑中的Exchange总是收到公司的邮箱发来的[存储空间不足的告警邮件] MicrosoftExchange329e71ec88ae4615bbc36ab6ce41109e@your ...

  6. 论文笔记:目标检测算法(R-CNN,Fast R-CNN,Faster R-CNN,FPN,YOLOv1-v3)

    R-CNN(Region-based CNN) motivation:之前的视觉任务大多数考虑使用SIFT和HOG特征,而近年来CNN和ImageNet的出现使得图像分类问题取得重大突破,那么这方面的 ...

  7. Java中的JDBC是什么?

    JDBC(Java Data Base Connectivity, Java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它有一组用Java语言编写的类和接 ...

  8. Spring MVC 复习笔记01

    1. springmvc框架 1.1 什么是springmvc spring mvc是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合.spring mvc是一个 ...

  9. linux性能分析命令1:top命令

    转载:http://www.cnblogs.com/peida/archive/2012/12/24/2831353.html top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的 ...

  10. wamp 安装memcached

    PECL 的全称是 The PHP Extension Community Library ,是一个开放的并通过 PEAR(PHP Extension and Application Reposito ...