变量与参数传递

理解变量

抛弃变量是存储数据的盒子这一错误观念,

可以把python变量理解为附加在对象上的标注

来个栗子

a = [1, 2, 3]
b = a
a.append(4)
print(a, b) #[1, 2, 3, 4] [1, 2, 3, 4]
print(a is b)

说明:a和b引用同一个列表,而不是这个列表的副本,当为a添加一个元素时,a,b都发生改变并指向同一个列表,

很明显用变量是存储数据的盒子这一观念无法解释。

变量赋值

在python中,通常会说把某个变量分配给某个对象,绝不会说把某个对象分配给某个变量,因为对象在赋值之前就创建了。

a = 3

说明:对于python中的赋值语句,应该先读右边,对象在右边创建或获取,之后将左边的变量绑定到对象上,

这就像往对象上贴上标注。

变量只不过是标注,你无法阻止往对象上贴多个标注,贴的多个标注就是别名。

每个变量都有标识、类型和值,对象一旦创建它的标识就不会变,标识可以理解为对象在内存中的地址。

id()函数返回对象内存地址的整数表示,id是唯一的数值标识,在对象的生命周期中不会改变

标识通常用is运算符检查

==比较的是两个对象中保存的数据,

is比较的是两个对象的标识,is常用于变量与单例值之间的比较:

x is None:

x is not None:

变量分类

在python中,一切都是对象,变量存储的是对象的引用。

对象可以分为可变对象和不可变对象,可变与不可变是针对对象内容本身而言的。

对象分类 概念 包括
可变对象 对象创建后对象的内容是可以改变的 list, dict, set
不可变对象 对象创建后对象的内容是不可以改变的 bool, int, float, tuple, str, frozens

栗子

不可变对象

x = 1
y = x
print(id(x), id(y), id(1)) #postion 1 (8791467483984 8791467483984 8791467483984)
x += 1
print(id(x), id(y), id(1)) #postion 2 ( 8791467483984 8791467483984)

x, y同时指向对象1,在position1位置,id(x), id(y), id(1)的内存地址一样

x += 1, 开辟了新的内存空间,创建对象2,让x重新指向新的对象2,但是原来的对象1和对象1的内存地址并没有发生变化

优点:

减少重复对象对内存空间的占用

可变对象

可变对象的修改并不会开辟新的内存空间,而是直接在原内存空间上直接修改对象的内容

即对象的内存地址并不会改变,改变的是对象的内容

list1 = [1, 2]
print(list1, id(list1)) #position1 ([1, 2] 37249672)
list1.append(3)
print(list1, id(list1)) #position2 ([1, 2, 3] 37249672)

参数传递

python唯一支持的参数传递模式是共享传参。

共享传参指函数中的各个形参获得对应实参中各个引用的副本,即函数内部的形参是实参的别名。

x = 1
y = [1, 2]
def fun(a, b):
print(a is x, b is y) fun(x, y) #True True

说明:当调用函数fun(x, y)时,a和x共同指向数字1,b和y共同指向列表[1, 2],即形参a是实参x的别名,形参b是实参y的别名。

注意:不要使用可变的对象作为参数的默认值,否则可能会得到意想不到的结果。

def extend_element(ele, eles=[]):
eles.append(ele)
return eles list1 = extend_element('a')
list2 = extend_element(2, [1])
list3 = extend_element('b')
print(list1, '->', list2, '->', list3) #['a', 'b'] -> [1, 2] -> ['a', 'b']
print(list1 is list3) #True

说明:我们发现list1和list3指向同一个列表,这是为什么呢?

其实这个根源在于,默认值在定义函数时计算,通常在模块加载时,因此默认值变成了函数对象的一个属性。

python-对象与参数传递的更多相关文章

  1. Python 对象的引用计数和拷贝

    Python 对象的引用计数和拷贝 Python是一种面向对象的语言,包括变量.函数.类.模块等等一切皆对象. 在python中,每个对象有以下三个属性: 1.id,每个对象都有一个唯一的身份标识自己 ...

  2. python函数的参数传递问题---传值还是传引用?

    摘要:在python中,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象.不可更改对象的传递属于传值,可更改对象属于传引用.想要在函数中传递 ...

  3. python中的参数传递和返回值

    python中的参数传递类似java,有着自己的内存回收机制,这和C++有着很大的差别. 1.函数的参数传递: >>> a = [, , ] >>> def fun ...

  4. Python 对象(type/object/class) 作用域 一等函数 (慕课--Python高级,IO并发 第二章)

    在python中一共有两种作用域:全局作用域和函数作用域全局作用域:在全局都有效,全局作用域在程序执行时创建,在程序执行结束时销毁:所有函数以外的区域都是全局作用域:在全局作用域中定义的变量,都属于全 ...

  5. python对象的复制问题,按值传递?引用传递?

    这部分这篇博文说的很明白,转了过来 作者:winterTTr (转载请注明)http://blog.csdn.net/winterttr/article/details/2590741#0-tsina ...

  6. Python中的参数传递问题

    首先需要说明python中元组,列表,字典的区别. 列表: 什么是列表呢?我觉得列表就是我们日常生活中经常见到的清单. 例如:lst = ['arwen',123] 向list中添加项有两种方法:ap ...

  7. Python—函数的参数传递

    形参和实参 形参即形式参数,函数完成其工作时所需的信息.形参不占用内存空间,只有在被调用时才会占用内存空间,调用完了即被释放. 实参即实际参数,调用函数时传给函数的信息. # -*- coding: ...

  8. 1.python的函数参数传递

    1 Python的函数参数传递 看两个例子: a = 1 def fun(a): a = 2 fun(a) print a # 1 a = [] def fun(a): a.append(1) fun ...

  9. 『无为则无心』Python函数 — 29、Python变量和参数传递

    目录 1.Python的变量 (1)Python变量不能独立存在 (2)变量是内存中数据的引用 (3)注意点 2.了解变量的引用 3.Python的参数传递(重点) (1)示例 (2)结论 (3)总结 ...

  10. python征程3.0(python对象)

    1.python使用对象模型来存储数据.构造任何类型的值都是一个对象.”尽管python被当成一种面向对象的脚本的编程语言“,但你完全能够写出不使用任何类和实例的脚本. python对象都拥有三个特性 ...

随机推荐

  1. xiv存储操作

    XIV存储操作维护手册                       二○一二年七月 目录 1.      存储划分... 3 1.1.       定义Storage Pool 3 1.2.      ...

  2. 文末有福利 | IT从业者应关注哪些技术热点?

    7月14-15日,MPD工作坊北京站即将开幕,目前大会日程已经出炉,来自各大企业的技术专家,按照软件研发中心的岗位职能划分,从产品运营.团队管理.架构技术.自动化运维等领域进行干货分享,点击此[链接] ...

  3. POJ 1854 - Evil Straw Warts Live

    Description A palindrome is a string of symbols that is equal to itself when reversed. Given an inpu ...

  4. [No0000122]Donet 中间语言,反编译 .net IL 指令速查

    名称 说明 Add 将两个值相加并将结果推送到计算堆栈上. Add.Ovf 将两个整数相加,执行溢出检查,并且将结果推送到计算堆栈上. Add.Ovf.Un 将两个无符号整数值相加,执行溢出检查,并且 ...

  5. [daily][archlinux][rsync] rsync

    科普文档:https://wiki.archlinux.org/index.php/Rsync 之前改文件系统时,用过. 然而用的不太对,导致一部分文件的权限出了问题. [troubleshoot][ ...

  6. 图->遍历

    文字描述 从图中某一顶点出发遍历图中其余顶点,且使每一个顶点仅被访问一次,这一过程就叫图的遍历. 深度优先搜索:类似树的先根遍历:假设初始状态下,图中所有顶点都未曾被访问,则从某个顶点出发,访问此顶点 ...

  7. 手工sql注入简单入门

    1.判断是否可以注入: 数字型: 1.1在参数后面加一个引号',如果页面报数字number错误,则一定不是sql注入点:如果报数据库比如mysql.oracle之类的错误,则是一个sql注入点. 1. ...

  8. LDA学习小记

    看到一段对主题模型的总结,感觉很精辟: 如何找到文本隐含的主题呢?常用的方法一般都是基于统计学的生成方法.即假设以一定的概率选择了一个主题,然后以一定的概率选择当前主题的词.最后这些词组成了我们当前的 ...

  9. 深入理解Java虚拟机笔记

    1. Java虚拟机所管理的内存 2. 对象创建过程 3. GC收集 4. HotSpot算法的实现 5. 垃圾收集器 6. 对象分配内存与回收细节 7. 类文件结构 8. 虚拟机类加载机制 9.类加 ...

  10. JSON.parseObject 和 JSON.toJSONString

    JSON.parseObject,是将Json字符串转化为相应的对象:JSON.toJSONString则是将对象转化为Json字符串.在前后台的传输过程中,Json字符串是相当常用的,这里就不多介绍 ...