他山之石,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对此属性进行访问.一般而言,点(. ...
随机推荐
- MATLAB关系运算符和逻辑运算符
1 关系运算符 关系运算符用来比较两个数之间的大小关系,在Matlab中的关系运算符包括: < 小于 <= 小于或等于 > 大于 >= 大于或等于 = ...
- 谷歌将一些弱小的库从安卓代码移除Google Removes Vulnerable Library from Android
Google this week released the November 2018 set of security patches for its Android platform, which ...
- 使用Apache JMeter对SQL Server、Mysql、Oracle压力测试(二)
接着第一篇的写: 第三步,测试SQL Server数据库的性能: a.加载JDBC SQL Server驱动.添加线程组和设置线程属性和第二步一样,就不再赘述了: b.设置JDBC Connectio ...
- 关于常用mysql的文件
这个一般在做项目的时候会用到,直接建立函数啥的,后部直接调用 代码: class_database.py import pymysql SERVER_HOST = "192.168.1.1& ...
- BOM定时器,onresize
定时器 <body> <button onclick="stop()">吃药</button> <button onclick=" ...
- js识别ESC并关闭开窗
$(document).keyup(function(event) { switch (event.keyCode) { //ESC默认code为27 case 27: var index = par ...
- Docker 构建 RabbitMQ 集群
刚开始,关于RabbitMQ集群的搭建,我找到了这篇文章:Docker 安装 RabbitMQ 集群 从而找到了第三方的RabbitMQ集群容器 rabbitmq-server 但是这个容器只有3.6 ...
- 安卓 ToolBar 颜色样式设置
设置Toolbar弹出菜单的字体颜色和背景颜色,包括三个点菜单颜色和返回图标的颜色. 布局文件xml <LinearLayout xmlns:android="http://schem ...
- 在java中使用Mysql数据库,如何在MyBatis的xml里面处理时间为Int类型的数据
主要是将显示在页面上的数据变成日期格式,而不是相应的毫秒数,具体的做法如下: 1.首先需要在相关的xml文件里面修改时间为下面语句,其中reg_time为要修改的日期列名 FROM_UNIXTIME( ...
- windows 系统验证是否为正版
博客园里边写这种帖子,足以证明我有多无聊.话不多说,上干货. 一台计算器如果没有操作系统,就是一块大的板砖,拿起来抡人太重,放地上做床又太小. 如何查看自己操作系统呢?windows7 桌面找到我的电 ...