关于python的传参

本文探讨了Python中可变和不可变参数的传递方式。对于列表等可变对象,函数内部的修改会影响原始对象,因为它们是按引用传递。而对于字符串等不可变对象,尝试修改会导致TypeError,因为它们是按值传递。通过示例展示了如何在函数中改变不可变对象,并总结了Python参数传递的本质是对象引用,但根据参数类型表现为传值或传引用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

可变类型传参(列表)

def change_list(li, num, val):
    li[num] = val


l1 = [1, 2, 3, 4]
change_list(l1, 3, 5)
print(l1)

#结果
[1, 2, 3, 5]

由这里可以看出,python对于可变参数的传参方式为对象引用,假如l1在创建时指向的是内存的地址为A1.  即这里的传参相当于 li = l1>>A1 , 此时li l1指向同一块内存地址,所以li改变l1也改变。

其实所谓的改变实质是改变列表中存储的内存地址,如创建列表l1,则会在内存中开辟一块A1的内存地址,然后再开辟四块内存地址分别存储值[1,2,3,4],然后A1中分别存储这四个值的内存地址。当将列表中的4改变为5时,其实是开辟一块内存地址,存储值5, 而原来存储值4内存地址的内存地址,现在改为存储指向值5的内存地址

 不可变类型传参(字符串)

def change_string(s, num, val):
    s[num] = val


s = 'abc'
print(change_string(s, 2, 'd'))
print(s)


#结果
TypeError: 'str' object does not support item assignment

报错:因为字符串是不可变类型,我们不能直接更改原对象

改为如下代码:

def change_string(s, num, val):
    new_s = ''
    for index, value in enumerate(s):
        if index == num:
            value = val
        new_s += value
    return new_s

s1 = 'abc'
print(change_string(s1, 2, 'd'))
print(s1)


# 结果
abd
abc

由这里可以看出,python对于不可变类型的传参方式可以看为传值,因为不可对源对象进行修改,只能用源对象的值

总结

python的传参方式可以统一的看为“对象引用”,这种方式是传值和传引用的一种综合。

但是区分:可变参数或不可变参数。

如果是可变参数(列表,字典,集合)则相当于传引用的方式,可以对原始的对象进行修改。

如果是不可变参数(字符串、数字)等,则相当于传值的方式。不可以对原对象进行修改

### Python 中函数参数传递机制 Python 的函数参数传递机制并非传统的“值传递”或“引用传递”,而是采用了更为独特的“按对象引用传递”方式[^3]。这意味着,在函数调用过程中,实际上传递给函数的是对象的引用而非其副本。 #### 不可变对象的行为 对于不可变对象(如整数、字符串、元组等),当将其作为参数传递给函数时,任何试图修改该对象的操作都会创建一个新的对象实例。这是因为不可变对象的本质决定了它们无法被原地更改[^1]。 ```python def modify_value(x): x += 10 print(f"Inside function: {x}") a = 5 modify_value(a) print(f"Outside function: {a}") ``` 上述代码中,`a` 是一个不可变对象。尽管在 `modify_value` 函数内部对其进行了操作,但外部变量 `a` 并未受到影响。 #### 可变对象的行为 相比之下,可变对象(如列表、字典等)则允许在其原有基础上进行修改。如果将这样的对象作为参数传递至函数,则可以在函数体内直接改变它的状态,而这些变化会反映到原始对象上[^2]。 ```python def append_to_list(lst, value): lst.append(value) my_list = [1, 2, 3] append_to_list(my_list, 4) print(my_list) # 输出 [1, 2, 3, 4] ``` 此例展示了如何利用 Python传参机制来实现对列表内容的实际更新。 #### 关键字参数与默认值支持 除了常规的位置参数之外,Python 还提供了灵活的关键字参数功能以及设置默认值的能力。这使得定义更加复杂和多功能的接口成为可能[^5]。 ```python def greet(name="World", greeting="Hello"): print(f"{greeting}, {name}!") greet() greet("Alice", "Hi") greet(greeting="Good morning", name="Bob") ``` 以上示例说明了即使不提供全部所需参数的情况下也能正常执行的情况,因为部分参数已经有了预设好的缺省值[^4]。 ### 结论 综上所述,Python 使用了一种称为 “按对象引用传递”的独特方法来进行数据交换。这种设计结合了其他语言里常见的两种主要形式的优点,并针对不同型的数据结构采取相应策略以达到最佳效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值