一、函数式编程
“函数式编程”同“面向对象编程”,“面向过程编程”一样是一种编程范式,它属于”结构化编程”的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用。相比于面向对象,函数式编程的最大优点在于将计算机运算看做是数学中函数的计算,并且避免了状态以及变量的概念,关于函数式编程的更多知识还有待于学习,这里先埋个坑,以后再补。
二、闭包
简单来说,闭包是是引用了自由变量的函数,闭包包含自由(未绑定到特定对象)变量;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。例如以下例子:
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