python中函数陷阱

一、本地变量是静态检测的

python定义的在一个函数中进行分配的变量名是默认为本地变量的,它们存在于函数的作用域并只在函数运行时存在。python是静态检测python的本地变量的。看下面例子:

x = 99
def selector():
    print x
selector()

结果为99。

这里,函数中的x被解析为模块中的x。但是如果在引用之后增加一个赋值语句,看看会发生什么。

x = 99
def selector():
    print x
    x = 88
selector()

结果为:

Traceback (most recent call last):
  File "./test.py", line 13, in <module>
    selector()
  File "./test.py", line 11, in selector
    print x
UnboundLocalError: local variable 'x' referenced before assignment

得到了一个未定义变量名的错误,其原因是微妙的。在交互模式下输入或从一个模块文件中导入时,python读入并编译这级代码。在编译时,python看到了对x的赋值语句,并且决定了x将会再函数中的任一地方都将是本地变量名。但是,当函数实际运行时,因为在print执行时赋值语句并没有发生,python告诉你正在使用一个未定义的变量名。根据其变量名规则,本地变量x是再其被赋值前使用的。实际上,任何在函数体内的赋值将会使其成为一个本地变量名。


二、默认和可变对象

默认参数是在def语句运行时被评估并保存的,而不是在这个函数调用时。从内部来讲,Python会将每一个默认参数保存成一个对象,附加在这个函数本身。

这也是通常我们所想要的:因为默认参数是在def时被评估的,所以必要的话,它能够从整个作用域内保存值,但是因为默认参数在调用之前保存了一个对象,必须对修改可变的默认参数十分小心。例如:

def saver(x=[]):
    x.append(1)
    print x
saver([2])
saver()
saver()
saver()
结果为:

[2, 1]

[1]

[1, 1]

[1, 1, 1]


三、函数没有重载

class C:
    def meth(self, x):
        print x
    def meth(self, x, y, z):
        print x, y, z
这样的代码是会执行的,但是def只是在类的作用域把对象赋值给变量名,这个方法函数的最后一个定义是唯一保留的(就好像x = 1,然后x = 2,结果x将是2)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值