python 可变参数空值检测_python: 可变参数

结论:定义Python函数的默认参数时,默认参数必须指向不变对象!

事实上,编写程序时如 果可以设计成不变对象,就应该尽量设计成不变对象。

以下例子来自 The Hitchhiker’s Guide to Python .

假如定义函数:

def append_to(element, to=[]):

to.append(element)

return to

调用函数如下:

my_list = append_to(12)

print(my_list)

my_other_list = append_to(42)

print(my_other_list)

我们可能期待这样的结果:

[12]

[42]

实际上得到的是:

[12]

[12, 42]

究其原因,是因为Python默认参数的值在函数定义时即已经算好了,而不会在再次调用时再重新计算。在上述例子中,默认参数to也是一个变量,它指向了对象[],每次函数调用时,如果对象的内容已经改变,那么默认参数to指向内容自然也变了。

对List而言,List在定义时即被创立,只要名字不变,相同的List会一直被后续的调用使用,所以第二次调用时,得到的是已经被改变的List。

想避免上述问题,不使用可变参数即可。

假如真的需要传递一个List,可以使用如下方法:

def append_to(element,to=None):

if to is None:

to=[]

return to.append(element)

×上面表述多少有点易混淆,参数里的to和定义成List的to是否为不同的东西?它们是否指向了不同的地方?如果是,那么不应该使用同样的名字,因为那样容易使人以为两者是相同的。

一些额外的扩展。

这里设计到一个问题,即Python函数的参数是如何传递的?是call-by-name?还是call-by-reference?正确的说两者都不是,Python是call-by-object。

Python有一句话很重要:Everything is an object.

Python中“给一个变量赋值”,这里“变量”更准确的术语是names,“赋值”更准确的表述是“把name与一个object绑定起来”。

请看以下例子体会Python与其他语言的区别:

比如在C++中,

string str=”ABC”;

//…

str=”DEF”;

str指向内存中某一地址,该地址里面存的值是”ABC”;到后面,该内存里的内容被改写,变成”DEF”。

下面看在Python中的情况,

str=’ABC’

#…

str=’DEF’

一开始把name str与一个字符串对象’ABC’绑定;到后面name str与另一个字符串对象’DEF’绑定,但是原先的’ABC’对象并不受影响。

不难理解,一个object可以同时对应多个name。

因此,在Python中无论赋值也好函数调用也好,所做的只是把”作用域”与”对象”绑定起来,如果该对象是可变的,那么它的变化会超出”作用域“之外。

请看下面例子:

def (ele):

ele.append(1)

ele=[2]

m=[]

f(m)

print(m)

结果会是[1]而不是[2],因为List是可变的,append方法改变了m,但是赋值局部变量ele的行为对外面作用域是没有影响的,Python中赋值是给name绑定一个新对象,而不是改变对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值