Bullet:Python的函数中参数是引用吗?

别的语言中关于函数有传值和传引用的区分。

关于此,流传很广的一个说法是

他们在现象的区别之一就是值传递后的变化,受到影响的就是引用,未受到影响的就是传值。

在学习中,也曾碰到过这个问题,网上关于这个也是有着一些争论,各执一词。

但是官方文档中,却明确写着是call by object reference。

https://docs.python.org/2/tutorial/controlflow.html#id2

The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are passed using call by value (where the value is always an object reference, not the value of the object). [1] When a function calls another function, a new local symbol table is created for that call.

Actually, call by object reference would be a better description, since if a mutable object is passed, the caller will see any changes the callee makes to it (items inserted into a list).

call by object reference,那么以下代码段会让人产生疑问

[[email protected] python]# cat func.py
def func(a):
a = 2
return a

b = 1

func(b)

print b
[[email protected] python]# python func.py
1
[[email protected] python]#

其中b的值并未发生变化。

要解释这个问题,可以接住python提供的一个函数id。

[[email protected] python]# pydoc id
Help on built-in function id in module __builtin__:

id(...)
id(object) -> integer

Return the identity of an object. This is guaranteed to be unique among
simultaneously existing objects. (Hint: it‘s the object‘s memory address.)
 

将程序改写如下

[[email protected] python]# cat func.py
def func(a):
print "argu a id = %d , before assignment." % id(a)
a = 2
print "argu a id = %d , after assignment." % id(a)
return a

b = 1
print "Variable b id = %d , before calling function func." % id(b)

func(b)
print "Variable b id = %d , after calling function func." % id(b)
[[email protected] python]# python func.py
Variable b id = 14570296 , before calling function func.
argu a id = 14570296 , before assignment.
argu a id = 14570272 , after assignment.
Variable b id = 14570296 , after calling function func.
[[email protected] python]#

可以见到,变量b在函数调用前后的ID没有发生变化,值也未发生变化。在函数体内,在第一次赋值之前ID也未发生变化,但在赋值之后发生了变化。

正如官方文档描述的那样。

The execution of a function introduces a new symbol table used for the local variables of the function. More precisely, all variable assignments in a function store the value in the local symbol table; whereas variable references first look in the local symbol table, then in the local symbol tables of enclosing functions, then in the global symbol table, and finally in the table of built-in names. Thus, global variables cannot be directly assigned a value within a function (unless named in a global statement), although they may be referenced.

其实符合流传最广的那个说法是python中的复合类型,比如以下代码段

[[email protected] python]# cat func_1.py
a=[1]

def func(b):
b[0] = 2

func(a)

print a[0]
[[email protected] python]# python func_1.py
2

就如文档的脚注所言,如果传递的是可变的对象调用者可见到被调用者中间的变化。

所以,python中的函数传递就如官方文档所言,可叫做call by object reference,为何有不合流传较广的说法的现象出现,概由函数体内本地符号表的缘故,是一个新的引用。

而为啥会有区别,则要考虑python中有

可更改(mutable)与不可更改(immutable)对象

时间: 2024-11-05 02:19:02

Bullet:Python的函数中参数是引用吗?的相关文章

python main函数中变量默认为global variable

在python的main函数中的变量默认为全局变量,而其他的def函数中的变量则默认为局部变量. 当然,局部变量会优先于全局变量,在执行formal_print(t_global)语句时便可看出. 测试代码如下: <span style="font-size:18px;">#coding=utf-8 #测试python的全局变量,局部变量的机制 def formal_print(s_global):#常规的传参用法,传递参数进行print,变量名可任意 print &quo

python把函数作为参数

python把函数作为参数 在2.1小节中,我们讲了高阶函数的概念,并编写了一个简单的高阶函数: def add(x,y,f): return f(x)+f(y)print add(-5,9,abs) >>> 14 根据函数的定义,函数执行的代码实际上是: abs(-5) + abs(9) 由于参数 x, y 和 f 都可以任意传入,如果 f 传入其他函数,就可以得到不同的返回值. 任务 利用add(x,y,f)函数,计算: 计算平方根可以用函数: >>> math.s

C++ main函数中参数argc和argv含义及用法

argc 是 argument count的缩写,表示传入main函数的参数个数: argv 是 argument vector的缩写,表示传入main函数的参数序列或指针,并且第一个参数argv[0]一定是程序的名称,并且包含了程序所在的完整路径,所以确切的说需要我们输入的main函数的参数个数应该是argc-1个: 第一个参数argc用来存放命令行参数的个数第二个参数argv是指针数组,它是用来存放命令行中各个参数和命令字的字符串的 具体可看:C++ main函数中参数argc和argv含义

python进阶一(函数式编程)【2-1 python把函数作为参数】

2-1 python把函数作为参数 1 def add(x, y, f): 2 return f(x) + f(y) 如果传入abs作为参数f的值: 1 add(-5, 9, abs) 根据函数的定义,函数执行的代码实际上是: 1 abs(-5) + abs(9) 由于参数 x, y 和 f 都可以任意传入,如果 f 传入其他函数,就可以得到不同的返回值. 任务 利用add(x,y,f)函数,计算: 1 import math 2 3 def add(x , y , f): 4 return f

python函数中参数是如何传递的?

python中一切皆对象,函数中参数传递的是对象的引用. 1在函数中改变变量指向的对象,即指向不同对象. 当在函数中修改传递进来的变量指向另一个对象时,实参的对象不会改变. >>> def fun(num,l,d): ... num=123; ... l=[1,2,3] ... d={'a':123} ... print("inside:","num=%f,l=%s,d=%s"%(num,l,d)) ... >>> num=1 &

python函数中参数的传递

Python唯一支持的参数传递方式是『共享传参』(call by sharing)多数面向对象语言都采用这一模式,包括Ruby.Smalltalk和Java(Java的引用类型是这样,基本类型按值传递)共享传参是指函数的各个形式参数获得实参中各个引用的副本:也就是说,函数内部的形参是实参的别名(alias)这种方案的结果是,函数可能会修改作为参数传入的可变对象,但是无法修改那些对象的标识(即不能把一个对象替换为另一个对象. 1 >>> def fun(num,l,d): 2 ... nu

Python函数中参数前带*是什么意思?

背景 前几天看了些python的代码,发现有些函数的参数前带有()号,有的甚至有两个()号,它们代表什么意思的? 解释 查阅资料后发现,参数前面加上* 号 ,意味着参数的个数不止一个,另外带一个星号()参数的函数传入的参数存储为一个元组(tuple),带两个()号则是表示字典(dict) 下面我们实际操作一下: def t1(param1, *param2): print(param1) print(param2) t1(1,2,3,4) # 1 # (2,3,4) def t2(param1,

Python函数中参数* 和 ** 的区别

* 函数接收参数为元组 例如 def myfun(*args): #相当于 def myfun(1,2,3)    ==> args 就相当于(1,2,3) for a in args: print(a) ** 表示函数接收参数为一个字典 def myfun(**args) :#相当于 def myfun({a:1,b:2,c:3}) ==>args 就相当于{a:1,b:2,c:3} for k,v in args: print(k,":",v)

js函数中参数的传递

先看一道JS的笔试题: var setObj=function(o){ o.name="xiaoming"; o={}; o.name="xiaohong"; } var p={name:"xixi",age:24}; setObj(p); console.log(p); 答案是{name:xiaoming,age24}: 在JavaScript中函数参数默认为引用类型. 在阅读本章节之前建议参阅一下两章节:1.值类型可以参阅javascript