python充分理解def语句

        python中def是一个可执行语句,用来定义一个函数。当解释器执行def语句时,其会在内存中创建一个函数对象,除此之外,还会创建一个该函数对应的本地命名空间。这里需要注意的有两点:1 该命名空间是在执行def语句时就已经创建的,而不是在函数调用时; 2 这个命名空间中有包含哪些变量。

        对于2点,取决于函数签名已经函数类型。如果函数具有默认参数,那么该命名空间会包含默认参数变量,此外,如果该函数还是一个闭包,那么该命名空间还包含了外层函数的自由变量(即在外层函数定义,但是在内层函数中引用的变量)。

        由于在执行def语句时,其命名空间就已经创建,而不是在调用时创建,且后续调用时,无论多少次调用,每次调用函数生成的多个命名空间是共享这些变量(即默认参数以及自由变量)的,而不是每次调用重新定义这些变量,因为这些变量的定义在执行def语句(即定义函数时)就定义好了。因此,如果默认参数或者自由变量是可变对象,那么如果函数中有对这些对象做原地的修改,则这个修改会对所有的调用都起作用。

        看下面第一个例子。下面这个例子中,默认参数a是可变对象,且函数中对a进行了原地修改,根据上述的分析,后面每次调用f1,a并不会重新定义,而是在上次调用的基础上进一步进行修改更新a的值。

def f1(a=[1]):
    a.append(1)
    print(a)

f1() # output --> [1,1]
f1() # output --> [1,1,1]
f1() # output --> [1,1,1,1]

        再看下面的第二个例子。下面这个例子中,inner函数是一个闭包,其引用了外层函数的变量a,因此a作为自由变量会在inner函数的本地命名空间中。根据上述分析,多次调用f1,会对a的值不断更新;但是如果重新执行定义inner的def语句,就会重新创建一次inner的初始命名空间,所以其中的初始变量也会重新定义,因此调用f2不会在f1的基础上更新a的值,而是同样的在上一次f2调用的基础上更新a的值。

def outer():
    a = []
    
    def inner():
        a.append(1)
        print(a)
    
    return inner

f1 = outer()
f2 = outer()

f1() # output --> [1]
f1() # output --> [1,1]
f1() # output --> [1,1,1]

f2() # output --> [1]
f2() # output --> [1,1]
f2() # output --> [1,1,1]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值