Python高级编程——6.函数

 

递归、函数变量赋值、参数中的函数、匿名函数、闭包、偏函数

一、递归:

函数的递归,就是让在函数的内部调用函数自身的情况,这个函数就是递归函数。

注意:递归一定要有结束条件,否则就会成为一个死循环。

以下是两个递归函数的例子:


执行结果:



二、函数变量赋值:

我们可以将一个函数赋值给一个变量(注意,不是调用哦,下图t1的例子),这时这个变量也会指向该函数。


运行结果:


以上例子说明t1是复制的函数体,与printMsg不同名但是同一地址的函数,两个引用同时指向同一地址。



三、参数中的函数:

函数作为一个对象,我们同样可以将函数当成一个实际参数传递给另一个函数进行处理这个是动态语言才用的特性,也使得动态语言变得相当的灵活和好用哦~~~



这里将add()函数作为一个参数fn1传递给了fn()函数,在fn()函数内部调用了fn1()函数,也就是add()函数。



四、匿名函数:

例如:前面我们使用的在一个函数中,参数是另外一个函数。常规方式当我们调用的时候,需要创建一个函数,昨晚调用函数的参数。但是我们也可以使用匿名函数来完成。

匿名函数的格式如下:

无参匿名函数       lambda://代码

带参匿名函数   lambda  x,y :x+y


这样写的好处就是,代码简化,坏处就是降低了阅读性,且不能写多行

匿名函数的调用:



五、偏函数

常规函数操作中,我们在函数的参数中可以添加参数的默认值来简化函数的操作,偏函数也可以做到这一点,偏函数可以在一定程度上更加方便的管理我们的函数操作。

偏函数通过内置模块functools的partial函数进行定义和处理。

# functools.partial()函数语法结构

新函数名称 = functools.partial(函数名称, 默认赋值参数)

# 原始的2进制数据转换 int("111", base=2) 

~执行结果:7 

# 引入我们需要的模块functools import functools 

# 通过偏函数扩展一个新的函数int2

int2 = functools.partial(int, base=2) 

# 使用新的函数,新的函数等价于上面的

int("111", base=2) 

int2("111") 

~执行结果:7

   我们可以通过以下例子再次阐明: 求任意数和一个默认赋值参数的和

 

以上代码运行结果:


也就说sum()函数和new_sum()函数的两次调用结果是一样的,前者需要每次调用时都重复写默认参数y=5,而后者通过functools.partial(函数名,默认参数=默认值),每次调用时不必重复写默认参数,只需要给其他参数值即可。这就是偏函数,很大程度上简化了代码。



六、闭包:

在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包

javascript也是解释型语言,也有闭包的概念 。

请看下面的例子:


执行结果:


我们主要看一下res中保存内容,实则是inner函数在内存中的地址。分析函数运行的顺序:当外函数被调用时首先执行的是print(“外函数”),而inner()函数因为只是定义了,没有被调用,所以不会打印。return  inner,即返回的是inner函数的地址,将此地址赋值给res。请看内存分析图:



我们知道在堆内存中,释放内存是依据GC(垃圾回收),在堆内存中保存的数据如果没有引用指向它,GC检测到便会将其回收,如以上例子,若是嵌套函数,回收顺序是倒着回收,也就是先回收内函数。若将函数变成闭包,内存函数的地址重新被res指向,则导致不会被回收,整个函数将不会被释放,函数内的变量也会一直存在。

闭包思考:

1.闭包似优化了变量,原来需要类对象完成的工作,闭包也可以完成

2.由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存


6.1 看一个闭包的实际例子:

def line_conf(a, b):

    def line(x):

        return a*x + b

    return line

line1 = line_conf(11)

line2 = line_conf(45)

print(line1(5))

print(line2(5))

这个例子中,函数line与变量a,b构成闭包。在创建闭包的时候,我们通过line_conf的参数a,b说明了这两个变量的取值,这样,我们就确定了函数的最终形式(y = x + 1y = 4x + 5)。我们只需要变换参数a,b,就可以获得不同的直线表达函数。由此,我们可以看到,闭包也具有提高代码可复用性的作用。

如果没有闭包,我们需要每次创建直线函数的时候同时说明a,b,x。这样,我们就需要更多的参数传递,也减少了代码的可移植性。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值