Chinaunix首页 | 论坛 | 博客
  • 博客访问: 45659
  • 博文数量: 15
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 176
  • 用 户 组: 普通用户
  • 注册时间: 2014-01-31 01:57
个人简介

资深码农

文章分类

全部博文(15)

文章存档

2016年(3)

2014年(12)

我的朋友

分类: Python/Ruby

2016-09-16 23:46:05

对于刚接触Python不久的新手,Python的函数传参机制往往会让人迷惑。学过C的同学都知道函数参数可以传值或者传地址。比如下面这段代码

点击(此处)折叠或打开

  1. void func(int input) {
  2.     input = 100;
  3. }

  4. int a = 0;
  5. func(a);
  6. printf("%d", a);
结果应该是打印0,a的值自始至终都没有改变,因为传递给函数func的是a变量的一个拷贝。而下面这段代码,

点击(此处)折叠或打开

  1. void func(int* input) {
  2.     *input = 100;
  3. }

  4. int a = 0;
  5. func(&a);
  6. printf("%d", a);
则会打印100,因为传递给func的参数是变量a的地址。
那么Python遇到类似情况是怎么样处理的呢?以下摘自Mark Lutz的Learning Python第五版,
Python’s pass-by-assignment scheme isn’t quite the same as C++’s reference parameters
option, but it turns out to be very similar to the argument-passing model of the C
language (and others) in practice:
Immutable arguments are effectively passed “by value.” Objects such as integers
and strings are passed by object reference instead of by copying, but because
you can’t change immutable objects in place anyhow, the effect is much like making
a copy.
Mutable arguments are effectively passed “by pointer.” Objects such as lists
and dictionaries are also passed by object reference, which is similar to the way C
passes arrays as pointers—mutable objects can be changed in place in the function,
much like C arrays.
Of course, if you’ve never used C, Python’s argument-passing mode will seem simpler
still—it involves just the assignment of objects to names, and it works the same whether
the objects are mutable or not.
也就是说在Python中,不可变参数(Immutable arguments)都是可理解为传值的,而可变参数(Mutable arguments)都是可以理解为传地址的。而哪些类型是不可变参数呢,根据Mark的描述,numbers,strings,tuples都属于不可变,而list,dict都属于可变类型。看下面这段小程序,

点击(此处)折叠或打开

  1. def func(var1):
  2.     var1 = 10
  3. var2 = 200
  4. func(var2)
  5. print var2
func的传入参数是整数,值为200,在func内部,它试图把传入参数赋值为10,结果打印出来的值仍然是200,原因是func的参数是不可变类型。
再看下面这段程序,

点击(此处)折叠或打开

  1. def func(var1):
  2.     var1[0] = 100
  3. var2 = [3,4,5,6,7]
  4. func(var2)
  5. print var2[0]
func的传入参数是list,属于可变类型,而函数试图把这个list的第一个元素用100进行赋值,结果是var2的第一元素从3变为了100,最终打印出来的结果是100。
在实际工作中,如何保证参数在传递过程中不发生改变呢?一个办法是传递参数的一份拷贝,比如需要传一个列表L = [1,2,3]给函数func,那你可以写成func(L[:])。另一个办法是使用函数tuple,把list转换为tuple,像这样func(tuple(L))。



阅读(1533) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~