当前位置: 首页 > news >正文

网站建设技术 论坛手机软件开发语言

网站建设技术 论坛,手机软件开发语言,西昌市网站建设公司,在线制作网站表白文章目录一、对象的唯一id二、赋值三、可变对象和不可变对象四、函数的参数传递五、深拷贝和浅拷贝六、举个栗子6.1 不可变对象的拷贝6.2 可变对象的拷贝6.3 可变对象改变外层元素6.4 可变对象改变内层元素七、总结一、对象的唯一id python中的所有对象都有自己的唯一id#… 文章目录一、对象的唯一id二、赋值三、可变对象和不可变对象四、函数的参数传递五、深拷贝和浅拷贝六、举个栗子6.1 不可变对象的拷贝6.2 可变对象的拷贝6.3 可变对象改变外层元素6.4 可变对象改变内层元素七、总结一、对象的唯一id python中的所有对象都有自己的唯一idid在创建对象时就已经分配给对象id是对象的内存地址并且在每次运行程序时都不相同除了某些具有恒定唯一id的对象比如-5~256之间的整数。 id()返回对象的唯一id适用于python中的任何对象如变量、字符串、列表、字典、元胞等。 a 5 b hello c (1, 2, 3)print( id(a):, id(a)) print( id(b):, id(b)) print( id(c):, id(c))运行三次的结果 从上图可以看出整数5的id一直不变但另外两个变量id的每次重新运行程序的结果都不一样。 二、赋值 python中的赋值语句总是建立对象的引用值而不是简单的复制对象。因此python变量更像是指针而不是数据存储区域。如下例子 import numpy as npa [1, 2, 3, 4, 5] def fun(data_in):print(data_in, id, id(data_in))b data_inprint(b, id, id(b))b[0] 99print(b, id, id(b))print(data_in, id, id(data_in))return bprint(a, id, id(a)) b fun(a) print(a, id, id(a)) print(b, id, id(b))运行结果 【解释】在fun()函数中直接用等号赋值语句对b进行操作本质上是将data_in的地址赋给b因此主函数中的变量a和fun()函数中的变量b同时指向了同一个地址因此在fun()函数中对变量b的所有操作都影响到了主函数中的变量a 三、可变对象和不可变对象 可变对象包括列表list、集合set、字典dict 不可变对象整数int、浮点型float、字符串str、布尔型bool、元胞tuple。 判断一个对象是否是可变对象关键是看操作对象前后的内存地址是否发生变化如果对某个变量进行了操作但操作前后的内存地址不变说明这个变量是可变对象否则这个变量是不可变对象。 可变与不可变的关键是对象内容能否被修改而不是对象的指向能否被修改如下例子 a 1 print(a, id, id(a)) a 2 print(a, id, id(a))运行结果 【解释】a首先被赋值一个整数然后再被赋值为另一个整数到这里很多人会说了“int是可变对象”那可就大错特错了注意看可以发现两次输出的a变量的内存地址是不同的说明第一次给a赋值为一个整数1a指向了第一个内存地址address1第二次再给a赋值为另一个整数2a指向了第二个内存地址address2但“address1和address2中存放的内容分别是1和2”这个事实是不变的所以先后两次赋值并不是改变了对象的内容只是第二次赋值时创建了一个新对象a指向了这个新对象而已。也就是说变量a改变的只是指向而不是内容所以a是不可变对象。 四、函数的参数传递 值传递指在调用函数时将实际参数复制一份传递到函数中在函数中对参数进行修改不会到影响实际参数 引用传递只在调用函数时将实际参数的地址传递到函数中在函数中对参数进行的修改将影响到实际参数。 python既支持值传递也支持引用传递。解释器会查看对象引用即对象的内存地址指向的变量的类型如果变量是不可变对象那么函数参数作为值传递如果变量是可变对象那么函数参数作为引用传递。对于值传递的传参方式函数结束之后主函数中该变量值不发生变化对于引用传递的传参方式函数之后主函数中该变量值会发生变化。如下例子 def fun(p1, p2):p1 1p2.append(2)returna, b 0, [1] print(a, b) fun(a, b) print(a, b)运行结果 【解释】fun()函数的参数p1的传入为a是整数是不可变对象所以p1是值传递函数fun()运行结束后主函数中的a不发生变化参数p2的传入为b是列表是可变对象所以p2是引用传递p2指向变量b指向的内存地址所以当p2发生变化时同时会改变变量b的取值函数fun()运行结束后b发生改变。 不要使用可变对象作为函数默认参数比如下面例子 def fun(a, b[]):b.append(a)return bprint(fun(0)) print(fun(0)) print(fun(0))运行结果 【解释】因为函数fun()的第二个参数是可变对象所以并不是每次调用fun()函数时参数b的传入都是空列表。 为了避免此类问题可以使用如下代码代替 def fun(a, bNone):if b is None:b []b.append(a)return bprint(fun(0)) print(fun(0)) print(fun(0))五、深拷贝和浅拷贝 .copy()是浅拷贝.deepcopy()是深拷贝。 相同点两个操作都会创建一个新的对象新对象的id都和原始对象的id不同 本质区别拷贝出来的对象的id不同即内存地址不同。 import copya [1, 2, 3, 4, 5] b a # 直接用等号进行复制相当于引用 c a.copy() d copy.copy(a) e copy.deepcopy(a)print(a, id, id(a)) print(b, id, id(b)) print(c, id, id(c)) print(d, id, id(d)) print(e, id, id(e)) print()print(a[1], id, id(a[1])) print(b[1], id, id(b[1])) print(c[1], id, id(c[1])) print(d[1], id, id(d[1])) print(e[1], id, id(e[1]))运行结果 import copya [1, {}, 3, 4, 5] b a # 直接用等号进行复制相当于引用 c a.copy() d copy.copy(a) e copy.deepcopy(a)print(a, id, id(a)) print(b, id, id(b)) print(c, id, id(c)) print(d, id, id(d)) print(e, id, id(e)) print()print(a[1], id, id(a[1])) print(b[1], id, id(b[1])) print(c[1], id, id(c[1])) print(d[1], id, id(d[1])) print(e[1], id, id(e[1]))运行结果 【解释】 b是由a直接赋值得来的所以是引用b的所有属性都和a完全一致所以a和b的id一致且a[1]和b[1]的id一致 c和d是由a浅拷贝得来所以c, d和a的id不同但c, d的子对象和a的子对象的id相同 e是由a深拷贝得来所以e和a已经完全没有关系对象e和对象a的id不同且两个对象的每个可变子对象的id也不同 当a[1]2时a[1]是不可变对象所以不管是深拷贝还是浅拷贝拷贝得来的对象的第一个元素的id都和a[1]相同 当a[1]{}时a[1]是可变对象所以深拷贝对象e的子对象e[1]的id和a[1]的id不同。 六、举个栗子 6.1 不可变对象的拷贝 import copya (1, 2, 3) b a c copy.copy(a) d copy.deepcopy(a)print(a, id(a), id(a)) print() print(-------赋值/引用-------) print(b, id(a), id(b)) print() print(-------浅拷贝-------) print(c, id(a), id(c)) print() print(-------深拷贝-------) print(d, id(a), id(d))运行结果 由于a是不可变对象那么赋值、深浅拷贝之后的内存地址都和原对象相同即使是被重新赋值也只是新开辟了一块内存并让a对象指向了新赋值元素并不改变原有地址内的内容。 6.2 可变对象的拷贝 import copya [1, 2, 3] b a c copy.copy(a) d copy.deepcopy(a)print(a, id(a), id(a)) print() print(-------赋值/引用-------) print(b, id(b), id(b)) print() print(-------浅拷贝-------) print(c, id(c), id(c)) print() print(-------深拷贝-------) print(d, id(d), id(d))运行结果 Python任何时候的赋值都相当于引用所以b和a的id相同由于a是可变对象所以深浅拷贝得到的新对象c和d的id和a不同。 6.3 可变对象改变外层元素 import copya [1, 2, [3, 4]] b a c copy.copy(a) d copy.deepcopy(a) a.append(5)print(a, id(a), id(a)) print() print(-------赋值/引用-------) print(b, id(b), id(b)) print() print(-------浅拷贝-------) print(c, id(c), id(c)) print() print(-------深拷贝-------) print(d, id(d), id(d))运行结果 Python任何时候的赋值都相当于引用所以b和a的元素和id完全相同由于a是可变对象因此深浅拷贝之后id都发生变化由于改变的是a外层元素而深浅拷贝都拷贝了外层对象所以改变a的外层元素不影响c和d的id。 6.4 可变对象改变内层元素 import copya [1, 2, [3, 4]] b a c copy.copy(a) d copy.deepcopy(a) a[2].append(5)print(a, id(a), id(a)) print() print(-------赋值/引用-------) print(b, id(b), id(b)) print() print(-------浅拷贝-------) print(c, id(c), id(c)) print() print(-------深拷贝-------) print(d, id(d), id(d))运行结果 Python任何时候的赋值都相当于引用所以b和a的元素和id完全相同由于a是可变对象所以c和d的id和a不相同由于浅拷贝只拷贝外部对象对于内部对象只拷贝了元素引用所以当a的内部对象a[2]发生改变时c[2]的元素也会对应发生改变。 七、总结 Python中的赋值即引用进行赋值时不会开辟新的内存空间也不会产生一个新的变量单独存在只是在原有数据块上打上了一个新标签。当数据块的任意一个标签发生变化时本质是这个数据块发生变化那么指向这个数据块的任意标签都会发生变化。浅拷贝常见的形式切片aa[:]、工厂函数alist(a)、copy函数aa.copy()或acopy.copy(a)。浅拷贝只拷贝了最外层的对象子对象只是被拷贝了元素的引用即对象内的元素没有被拷贝深拷贝只有一种实现形式acopy.deepcopy(a)。深拷贝既拷贝了对象也拷贝了多层的嵌套子元素深拷贝得到的对象是一个完全全新的对象和原对象不再有任何关联。 本文完整的pdf请关注“张张学算法”并回复“015”获取~
http://www.hkea.cn/news/14360124/

相关文章:

  • 从零开始建设网站0fees 安装 wordpress
  • 门户网站如何运营利用小程序反向做网站
  • 做网站最清晰的字体建设九九网站
  • 西安印象网站建设wordpress 404
  • 网站建设zg886网站建设中怎样设置背景
  • 烟台做网站优化园林景观设计案例网站
  • 电商网站网址大全建立网站的步骤筝晃湖南岚鸿官网
  • 布吉网站设计免费网页注册
  • 成华区建设局网站WordPress网校系统
  • cpa建站教程wordpress基础
  • 专门做中式装修的网站html5国外网站模板html源码下载
  • iis网站压缩网站建设狼盾网络
  • 一个空间放几个网站大型网站建设哪个好
  • 一级a做爰网站建筑培训学校
  • 南京cms建站网站开发前端和后端技术
  • 贵阳网站建设哪家好方舟电脑上制作网站的软件
  • 破解版 wordpress天津seo方案
  • 58做网站联系电话查企业数据要去什么网站
  • 洛阳住房和城乡建设部网站老房改造 装修公司
  • 上海海宏建设集团网站8090设计网站
  • 酒店网站如何做顺德网站建设渠道
  • 网站变exe文件怎么做婚庆网站设计说明书
  • 新乡市建设局网站wordpress运行机制
  • 岳池网站建设快手作品推广网站
  • 网站建设工具哪个好用网站图片怎么优化
  • wordpress新闻站自动采集器天津网站优化指导
  • 湖南养老院中企动力网站建设net开发网站
  • 嘉兴网站排名自己建的网站如何推广
  • 网站域名com和cn的差别在哪里企业公众号开发
  • 专注徐州网站开发排名软件