python中函数参数是引用还是传值

本文详细探讨了Python中变量传递的机制,包括字符串、元组、数字与列表等不同数据类型在函数调用时的传引用与传值行为,通过实例分析解释了Python中数据传递的本质,帮助开发者理解Python内存管理和函数参数处理的过程。

在《python核心编程》中看到:“python 是通过引用调用的,... ,但对不可变对象而言,函数的行为将类似按值传递”。但是我尝试编写以下函数,输出却不是如料想的:

    x = x * 2
    print "local x : " ,x

#############

x = 1
func(x)
print "global x : ", x


这段代码的输出如下:

local x : 2
global x : 1


 
也就是说,所谓的传引用并没有发生,这个情况让人特别纠结,后来看了一个很好的博客:python传值还是传引用,知道一个道理: 

在python中,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象。于是我又知道了对于数据而言,该行为将会导致生成一个新的临时对象,并对该临时对象进行操作。但是我又测试了以下代码,发现还是跟想象的不一样:

def func(x):
    x = x * 2
    print "local x : " ,x

#############

x = [1,2,3]
func(x)
print "global x : ", x
这段代码的输出为:

local x : [1,2,3,1,2,3]
global x : [1,2,3]
可以看出,这个时候仍然不是我们想象的传引用。但是随即将 func 函数改为如下形式:

def func(x):
    x *= 2
    print "local x : " ,x

则输出为:
local x : [1,2,3,1,2,3]
global x : [1,2,3,1,2,3]
这两个 func 函数的区别仅在于一个用的是等于乘法结果值,一个用的是乘等,在C++中,这两个操作的结果是一样的(虽然调用了不同的操作符)。但在 python 中,调用等号将会导致创建一个新的对象,这个对象与原对象并不是同一对象。所以第一个func 并没有改变全局 x 的值。

可以体会一下以下输出:

i = 1
id(i)    #输出40404792
id(1)  #输出40404792

i= 2
id(i)  #输出40404780

dic = ['1']
id(dic)  #输出40754232

dic = ['2']
id(dic)  #输出47922912

dic *= 2
id(dic)   #输出47922912

### Python 中子类调用父类函数时参数递方式 在 Python 中,无论是子类还是其他任何上下文中,当调用带有参数的函数或方法时,所使用的都是按对象引用递机制。这意味着对于不可变数据类型(如整数、字符串),行为类似于;而对于可变数据类型(列表、字典等),则更像是引用。 #### 不可变类型的参数递 考虑一个简单的例子来展示如何处理不可变类型的数据: ```python class ParentClass: def modify_value(self, value): value += 10 # 尝试修改入的数 print(f"Inside parent method: {value}") class ChildClass(ParentClass): pass child_instance = ChildClass() original_value = 5 print(f"Before calling parent's method: {original_value}") child_instance.modify_value(original_value) print(f"After calling parent's method: {original_value}") # 输出不会改变 ``` 在这个案例里,`modify_value()` 方法试图增加 `value` 的,但这并不会影响到原始变量 `original_value`,因为整型是不可变得,在这里表现为特性[^1]。 #### 可变类型的参数递 现在看看涉及可变对象的情况: ```python class ParentClass: def update_list(self, lst): lst.append('new item') # 修改列表内容 print(f"List inside the parent class after modification: {lst}") class ChildClass(ParentClass): pass child_instance = ChildClass() my_list = ['item1', 'item2'] print(f"Original list before call: {my_list}") child_instance.update_list(my_list) print(f"Updated list outside of function: {my_list}") # 列表确实发生了变化 ``` 这段代码展示了即使是在不同的作用域内操作同一个列表对象,对其所做的更改也会反映在整个程序中,这表明了对于像列表这样的容器类型来说,实际上是以一种近似于引用的方式工作的[^2]。 综上所述,在 Python 中通过 `super()` 或者直接指定父类名称的方式来调用父类的方法时,参数总是按照上述规则进行递——具体取决于这些参数所属的数据类型是否允许内部状态的变化而被外部观察到。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值