他山之石,calling by share——python中既不是传址也不是传值
无论对不变类型变量、可变对象赋值
不可变类型例子1a = 1
b = a
a = 3
print(a,b)
# 3 1可变类型例子2L1 = [1,2,3]
L2 = L1
L1 = 13
print(L1,L2)
# 13 [1, 2, 3]
L1 = ['a','b','c']
print(L1,L2)
# ['a', 'b', 'c'] [1, 2, 3]
L1 = [1,2,3]
L2 = L1
L1[1] = 13
print(L1,L2)
# [1, 13, 3] [1, 13, 3]
L1 = ['a','b','c']
print(L1,L2)
# ['a', 'b', 'c'] [1, 13, 3]
为什么说是调用方法修改属性呢?因为运算符重载中告诉我们,其实"[]"索引其实是自动调用了__getitem__方法(P713)。
记住以上两条,那么即可自如地应对python中参数传递的问题:
代码1:def testImmutable(arg):
arg = 2
print(arg)
a = 1
testImmutable(a)
# 2
print(a)
# 1这个用"对变量赋新值都会断开对原值的引用,而成为新值的引用"解释即可,所以这样的函数无法修改不可变对象。当然,可变对象也是不可以修改代码2:def testMutable(arg):
arg = ['a','b','c']
print(arg)
L = [1,2,3]
testMutable(L)
# ['a', 'b', 'c']
print(L)
# [1, 2, 3](这一点可以跟后面补充内容部分的JS的例子做对比)但是我们可以用方法修改可变对象的属性代码3:def testAttr(args):
args.append(1.3)
a = [1.1,1.2]
print(a)
# [1.1, 1.2]
testAttr(a)
print(a)
# [1.1, 1.2, 1.3]******************************♣******************************P530提到了一个陷阱也就是说我如果想要让形参默认为一个空列表,如果写成这样是有问题的:def saver(x=[]): # Saves away a list object
x.append(1) # Changes same object each time!
print(x)
saver([2]) # Default not used
# [2, 1]
saver() # Default used
# [1]
saver() # Grows on each call!
# [1, 1]
saver()
# [1, 1, 1]这是因为,这个空列表对象只是在def语句执行时被创建的,不会每次函数调用时都得到一个新的列表,所以每次新的元素加入后,列表会在原来的基础上变大,因为这个空列表在每次函数调用的时候都没有被重置正确写法如下:def saver(x=None):
if x is None: # No argument passed?
x = [] # Run code to make a new list each time
x.append(1) # Changes new list object
print(x)
saver([2])
# [2, 1]
saver() # Doesn't grow here
# [1]
saver()
# [1]
如下代码也会报错x = 11
def selector():
print(X)
X = 88
selector()
引用是C++中的概念,其操作符是: & ,这跟C中是取地址操作符一样,
但是意义不一样,C中没有引用的。 (切记 !)
传值,
是把实参的值赋值给行参
那么对行参的修改,不会影响实参的值
传地址
是传值的一种特殊方式,只是他传递的是地址,不是普通的如int
那么传地址以后,实参和行参都指向同一个对象
传引用
真正的以地址的方式传递参数
传递以后,行参和实参都是同一个对象,只是他们名字不同而已
✿例如有人名叫王小毛,他的绰号是“三毛”。说“三毛”怎么怎么的,其实就是对王小毛说三道四。
int num = 10;String str = "hello"; //String是一个引用类型
num = 20;str = "java";‘
void foo(int value) {value = 100;}foo(num); // num 没有被改变
这很容易理解,因为我们传递的是值的副本
void foo(String text) {text = "windows";}foo(str); // str 也没有被改变
str存着地址0x11
StringBuilder sb = new StringBuilder("iphone");void foo(StringBuilder builder) {builder.append("4");}foo(sb); // sb 被改变了,变成了"iphone4"。
sb是一个StringBuilder对象,他的地址0x21被传递给builder
StringBuilder sb = new StringBuilder("iphone");void foo(StringBuilder builder) {builder = new StringBuilder("ipad");}foo(sb); // sb 没有被改变,还是 "iphone"。
public class TestMain {public static void main(String[] args) {List<Integer> list = new ArrayList<Integer>();for (int i = 0; i < 10; i++) {list.add(i);}add(list);for (Integer j : list) {System.err.print(j+",");;}System.err.println("");System.err.println("*********************");String a="A";append(a);System.err.println(a);int num = 5;addNum(num);System.err.println(num);}static void add(List<Integer> list){list.add(100);}static void append(String str){str+="is a";}static void addNum(int a){a=a+10;}}
打印出来的结果是:
var obj = {x : 1};function foo(o) {o = 100;}foo(obj);console.log(obj.x); // 仍然是1, obj并未被修改为100.
如果是按引用传递,修改形参o的值,应该影响到实参才对。但这里修改o的值并未影响obj。 因此JS中的对象并不是按引用传递。那么究竟对象的值在JS中如何传递的呢?
他山之石,calling by share——python中既不是传址也不是传值的更多相关文章
- python中导入一个需要传参的模块
最近跑实验,遇到了一个问题:由于实验数据集比较多,每次跑完一个数据集就需要手动更改文件路径,再将文件传到服务器,再运行实验,这样的话效率很低,必须要专门看着这个实验,啥时候跑完就手动修改运行下一个实验 ...
- python 中的metaclass和baseclasses
提前说明: class object 指VM中的class 对象,因为python一切对象,class在VM也是一个对象,需要区分class对象和 class实例对象. class instance ...
- Python中的内置函数
2.1 Built-in Functions The Python interpreter has a number of functions built into it that are alway ...
- Python中super()的用法
参考链接:https://www.cnblogs.com/shengulong/p/7892266.html super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是 ...
- python中的__enter__ __exit__
我们前面文章介绍了迭代器和可迭代对象,这次介绍python的上下文管理.在python中实现了__enter__和__exit__方法,即支持上下文管理器协议.上下文管理器就是支持上下文管理器协议的对 ...
- python中GIL和线程与进程
线程与全局解释器锁(GIL) 一.线程概论 1.何为线程 每个进程有一个地址空间,而且默认就有一个控制线程.如果把一个进程比喻为一个车间的工作过程那么线程就是车间里的一个一个流水线. 进程只是用来把资 ...
- OpenCV-Python(1)在Python中使用OpenCV进行人脸检测
OpenCV是如今最流行的计算机视觉库,而我们今天就是要学习如何安装使用OpenCV,以及如何去访问我们的摄像头.然后我们一起来看看写一个人脸检测程序是如何地简单,简单到只需要几行代码. 在开始之前, ...
- 如何将xml转为python中的字典
如何将xml转为python中的字典 import cElementTree as ElementTree class XmlListConfig(list): def __init__(self, ...
- Python 中的属性访问与描述符
在Python中,对于一个对象的属性访问,我们一般采用的是点(.)属性运算符进行操作.例如,有一个类实例对象foo,它有一个name属性,那便可以使用foo.name对此属性进行访问.一般而言,点(. ...
随机推荐
- vue axios中文文档详解
英文文档:https://github.com/axios/axios 参考:https://www.jb51.net/article/123485.htm
- python的库小全
环境管理 管理 Python 版本和环境的工具 p – 非常简单的交互式 python 版本管理工具. pyenv – 简单的 Python 版本管理工具. Vex – 可以在虚拟环境中执行命令. v ...
- javascript将base64编码的图片数据转换为file并提交
/** @param base64Codes 图片的base64编码 */ function sumitImageFile(base64Codes){ var form=document.forms[ ...
- js 闭包,作用域,this 终结篇(转)
之前有写过闭包,作用域,this方面的文章,但现在想想当时写的真是废话太多了,以至于绕来绕去的,让新手反而更难理解了,所以就有了此篇文章,也好和闭包,作用域,this告一段落. 第一个问题:什么是闭包 ...
- Tarjan求LCA
LCA问题算是一类比较经典的树上的问题 做法比较多样 比如说暴力啊,倍增啊等等 今天在这里给大家讲一下tarjan算法! tarjan求LCA是一种稳定高速的算法 时间复杂度能做到预处理O(n + m ...
- WC.exe【C】
gitee传送门!!!(电脑打不开github,多次尝试未果,决定先用gitee存着先) 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命令行程序 ...
- 常用MSSQL语句
现在很少用SQL 写东西,但有时真用起来半天想不起来,看来还是有必要记录一下... 新建表: create table [表名] ( [自动编号字段] int IDENTITY (1,1) PRIMA ...
- 打造RecyclerView的n级列表
先上效果图: 1.该多级列表的优势: 支持无限级列表展开 基于一个recyclerView实现 可以自定义每一级item的样式,定制化更强 2.设计的思路 数据结构List,ItemBean类中有变量 ...
- sitecore 8.2 item属性查询
查询: query:/sitecore/content/[@@templatename='Homepage'] 结果: home (name: home, path: /sitecore/conten ...
- C# 正则表达式提取字符串中括号里的值
version = Regex.Replace(str, @"(.*\()(.*)(\).*)", "$2"); //小括号() Regex rgx = new ...