python中是按值传递参数还是按引用传递参数

在学习python函数的时候,遇到了一个非常有趣的问题:

在函数中的参数是如何传递的:是传值?还是传引用?当然,结果我们是知道的,肯定是传引用的。

现在,我们来测一下我们的结论:

=====

修改list,Code:

# 添加了一个string类型的元素添加到末尾

def ChangeList(lis):
    lis.append('hello i am the addone')
    print lis
    return

is = [1, 2, 3]
ChangeList(lis)
print lis

输出结果为:
[1, 2, 3, 'hello i am the addone']

[1,2, 3,'hello i am the addone']

由此可以知道,我们传递参数是传递的引用。。。。。。


那么,看到别人的一个例子,我们就会觉得这里面还是有学问的。。

那么我们来修改一个字符串,试试。


修改string,Code:

<span style="font-size:18px;">#修改字符串

def ChangeString(string):
    string = 'i changed as this'
    print string
    return

string = 'hello world'
ChangeString(string)
print string

</span>

输出结果为:
i changed as this

hello world

@-@ 说好的传引用呢??

为什么在函数外面输出的时候还是hello world的呢?

原来,我们知道在python中, string类型是不能够改变的。。

比如说我们在ChangeString中改变string的话,事实上,我们是没有改变传入的string的,我们仅仅作是事情是,新建一个string对象,然后把它给赋值,而已。


那如何来验证,我们上面的这一句话呢?

修改字符串again,Code:

<span style="font-size:18px;">#修改字符串again,输出string的id

def ChangeString(string):
    string = 'i changed as this'
    print string, '--- id :', id(string)
    return

string = 'hello world'
ChangeString(string)
print string, '--- id :', id(string)

</span>

输出结果为:

i changed as this --- id : 4353556584
hello world --- id : 4353554688

我们可以看到,他们的id是不同的,所以也就是说他们根本不是相同的对象。

也就是说,我们传的还是引用,但是,对于不可改变的数据类型,我们不能修改。。。如果你“修改”了,事实上我们是新建一个对象来进行对待的。。

传入的还是引用,这句话还是不错的。


========


结论:

我们知道,在python中,函数传参,还是传入的引用,而不是值。。

对于不可以改变和可以改变的数据类型,在函数调用的时候,会有不同的处理方式。。


======

知识总结尚浅,需要更多的学习,以后继续更新。。。

<think>我们刚刚讨论过Python函数的基本用法,现在用户提出了一个关于参数传递机制的具体问题:Python函数参数传递值传递还是引用传递?这个问题在Python中需要深入理解,因为Python参数传递机制既不是纯粹的值传递,也不是纯粹的引用传递,而是所谓的“共享传递”(Callbysharing)。在Python中,所有的数据都是对象,变量实际上是对对象的引用。当我们将一个变量传递给函数时,实际上传递的是这个引用的拷贝(即值传递方式传递引用)。这意味着:-如果参数是不可变对象(如整数、字符串、元组等),函数内部对参数的修改不会影响原始对象,因为不可变对象本身不能被修改。-如果参数是可变对象(如列表、字典等),函数内部对参数的修改会影响到原始对象,因为函数内部外部使用的是同一个对象。下面我们用代码示例来说明:</think> ### Python函数参数传递机制解析 Python参数传递既不是纯粹的值传递(pass by value),也不是纯粹的引用传递(pass by reference),而是采用 **对象引用传递(pass by object reference)** 机制。以下是关键原理验证代码: #### 核心机制: 1. **传递对象引用**:函数接收的是实参指向对象的**内存地址的副本** 2. **可变与不可变对象差异**: - 对**不可变对象**(int, str, tuple等):函数内修改会创建新对象 - 对**可变对象**(list, dict等):函数内修改直接影响原对象 #### 验证代码: ```python def modify_data(immutable_arg, mutable_arg): print("\n函数内初始状态:") print(f"immutable_arg 地址: {id(immutable_arg)}") print(f"mutable_arg 地址: {id(mutable_arg)}") # 修改不可变对象 immutable_arg += 100 # 修改可变对象 mutable_arg.append(4) print("\n函数内修改后:") print(f"immutable_arg 地址: {id(immutable_arg)}") print(f"mutable_arg 地址: {id(mutable_arg)}") # 测试数据 num = 10 # 不可变对象 my_list = [1,2,3] # 可变对象 print("调用前原始数据:") print(f"num 地址: {id(num)} | 值: {num}") print(f"my_list 地址: {id(my_list)} | 值: {my_list}") modify_data(num, my_list) print("\n调用后原始数据:") print(f"num 值: {num}") # 保持原值 print(f"my_list 值: {my_list}") # 已被修改 ``` #### 执行结果分析: ``` 调用前原始数据: num 地址: 140726300298208 | 值: 10 my_list 地址: 2048302561408 | 值: [1, 2, 3] 函数内初始状态: immutable_arg 地址: 140726300298208 # 与外部num相同地址 mutable_arg 地址: 2048302561408 # 与外部my_list相同地址 函数内修改后: immutable_arg 地址: 140726300299488 # 新地址(创建了新int对象) mutable_arg 地址: 2048302561408 # 地址不变(修改原对象) 调用后原始数据: num 值: 10 # 未改变 my_list 值: [1, 2, 3, 4] # 已改变 ``` #### 关键结论: 1. **对象引用副本**传递:函数参数获得原始引用的副本 2. **重新赋值 vs 就地修改**: - `immutable_arg += 100` → 创建新对象并绑定到局部变量 - `mutable_arg.append(4)` → 直接修改共享对象 3. **内存地址不变性**:可变对象在函数内外的内存地址相同 4. **副作用限制**:不可变对象在函数内修改不会影响外部变量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值