Python装饰器与函数式编程

一、函数式编程

“函数式编程”同“面向对象编程”,“面向过程编程”一样是一种编程范式,它属于”结构化编程”的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用。相比于面向对象,函数式编程的最大优点在于将计算机运算看做是数学中函数的计算,并且避免了状态以及变量的概念,关于函数式编程的更多知识还有待于学习,这里先埋个坑,以后再补。

二、闭包

简单来说,闭包是是引用了自由变量的函数,闭包包含自由(未绑定到特定对象)变量;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。例如以下例子:

def addX(x):
    def addY(y):
        return x+y
    return addY

在上述代码中,x就是自由变量,addY就是一个闭包,我们可以利用数学中的复合函数概念帮助我们理解闭包,即f(g(x)),给定一个参数x,先调用函数g(x)返回一个值,当做函数f的参数,最后再进行调用。

三、装饰器

Python中装饰器的作用对应于OOP中的装饰模式,他可以在不改变一个函数原有功能的基础上给函数动态的增加功能,这也是函数式编程的优势所在,可以在不修改原代码的基础上,利用最简单明了的方法给函数动态增加功能。关于装饰器的更详细说明可以参考廖雪峰Python教程接下来举一个例子帮助理解python装饰器。

def connect(function):
    @functools.wraps(function)
    def wrapper(obj,*args,**kwargs):
        function(obj,args,kwargs)
        print(" is connected")
    return wrapper

@connect
def click(obj,*args,**kwargs):
    print("{} is clicked".format(obj))

click("button") #button is clicked is connected

在上述代码中,我们利用python的语法糖@,在函数前加@connect相当于调用click = connect(click)
此时的click其实是返回的wrapper函数,于是我们可以在wrapper函数的定义中给函数做一些额外的工作增加其功能。此时的click其实是wrapper,当我们调用click._name_方法获取函数名时我们会发现结果为wrapper,为了防止有些用到函数签名的方法,我们引入@functools.wraps(function)修改函数名。

当我们的装饰器本身需要传入参数时,我们可以给connect函数再包装一层:

def connect_with(slot:str):
    def connect(function):
        @functools.wraps(function)
        def wrapper(obj, *args, **kwargs):
            function(obj, args, kwargs)
            print("{} is connected".format(slot))
        return wrapper
    return connect

@connect_with("measure")
def click(obj,*args,**kwargs):
    print("{} is clicked".format(obj))

click("button")     #输出为button is clicked   measure is connected

这时,我们在函数前加@connect_with(slot),相当于执行了click = connect_with(“measure”)(click)
我们可以从外到里一步一步解析,connect_with(“measure”)返回connect函数,于是connect_with(“measure”)(click)相当于connect(click),connect(click)函数返回wrapper函数,于是调用click函数就相当于调用了wrapper函数,当我们去掉@functools.wraps(function)装饰器打印函数click的名字时我们就会发现他其实是wrapper函数。

Python支持面向对象,面向过程以及部分函数式编程,我们可以在程序中灵活运用,这样可以大大提高开发效率。刚看完这么一个强大的功能,现在就去用用看,不说了0.0

猜你喜欢

转载自blog.csdn.net/wingwc/article/details/78413191