闭包
闭包就是一个 函数 和与其相关的引用环境组合的一个整体。
在 Python 中,闭包也被称为闭包函数或者闭合函数,与 局部函数 类似,不同之处在于,闭包中外部函数返回的不是一个具体的值,而是一个函数。一般情况下,返回的函数会赋值给一个 变量,这个变量可以在后面被继续执行调用。
语法:
def func(param):
def func_inner(base):
pass
return func_inner
实例:
def func():
def func_inner():
print("调用内层函数")
return func_inner
f0=func()
f0()#输出:调用内层函数
这样我们实际上就把func_inner实例留存在f0了。
装饰器
以一个记录运行时间的装饰器和一个计算并输出阶乘的函数为例:
'''记录并输出程序运行时间的装饰器'''
import datetime
import time
def CountTime(func):
def inner():
start = time.time()
func()
end = time.time()
print('用时:{}秒'.format(end-start))
return inner
@CountTime
def testFunc():
a = []
for i in range(1, 100):
j, k = i, 1
while j > 1:
k = k * j
j = j - 1
str0=str(i)+"!="+str(k)
print(str0)
a.append(str0)
print(a)
可以看出,这玩意虽然看起来很像注解,但是实际功能和定义方法还是存在很大区别的。
如果我们想用装饰器修饰一个带参的函数呢?
'''记录并输出程序运行时间的装饰器'''
import datetime
import time
def CountTime(func):
def do(numberRange):
t0 = time.time()
func(numberRange)
t = time.time() - t0
print("运行完毕,用时:" + str(t))
return do
@CountTime
def testFunc(numberRange):
a = []
for i in range(1, numberRange):
j, k = i, 1
while j > 1:
k = k * j
j = j - 1
str0 = str(i) + "!=" + str(k)
print(str0)
a.append(str0)
print(a)
testFunc(100)
#当然也可以这样调用(不加装饰器,直接用闭包语法)
c=CountTime(testFunc(100))
#或者这样(不加装饰器,直接用闭包语法)
#这样可以把未增强的函数保留下来,同时也能用一个变量存放实例化的增强过的函数
c=CountTime(testFunc)
c(100)
依然是原来的情景和需求。这里我们引入一个**[参数]与[被修饰函数]相同的[嵌套函数]**来完成。
这时,这个用法就让人联想起另一个东西:
Java切面编程的手动实现。
多个装饰器叠加
装饰器可以多个同时使用,调用顺序按从下向上
@wraps装饰器
用于装饰装饰器,防止调用一个被装饰器装饰的函数时,其name属性为装饰器内部函数的name而非被装饰函数的name,实例下参
'''记录并输出程序运行时间的装饰器'''
import datetime
import time
def CountTime(func):
def do(numberRange):
t0 = time.time()
func(numberRange)
t = time.time() - t0
print("运行完毕,用时:" + str(t))
return do
@CountTime
def testFunc(numberRange):
a = []
for i in range(1, numberRange):
j, k = i, 1
while j > 1:
k = k * j
j = j - 1
str0 = str(i) + "!=" + str(k)
print(str0)
a.append(str0)
print(a)
print(testFunc.__name__)
testFunc.__name__#输出为do
而在装饰器内部嵌套函数加入@wraps装饰器后:
'''记录并输出程序运行时间的装饰器'''
import time
from functools import wraps
def CountTime(func):
@wraps(func)
def do(numberRange):
t0 = time.time()
func(numberRange)
t = time.time() - t0
print("运行完毕,用时:" + str(t))
return do
@CountTime
def testFunc(numberRange):
a = []
for i in range(1, numberRange):
j, k = i, 1
while j > 1:
k = k * j
j = j - 1
str0 = str(i) + "!=" + str(k)
print(str0)
a.append(str0)
print(a)
print(testFunc.__name__)
testFunc.__name__
#输出testFunc
生成器
语法:用yield代替return
作用:实际上,带有yield的函数并不会在输出生成器时执行完毕,而是在yield关键字处停留,直到用遍历或next()输出内容时函数才会完整执行或执行一次循环。
函数定义标准写法
1.注释
紧挨’def func():'一行,用三引号字符串直接写出。
可用help()函数获取
2.类型注释
语法:
def add(a:int, b:float) -> str:
'''输入int和float类型,输出string类型'''
return a+b
类型注释只能用于标注作者期望的传入数据类型,在传入数据与注释不符时不会报错
偏函数partial
作用:截取部分函数/指定函数一部分参数
语法:
square=functools.partial(pow,2)
ef add(a:int, b:float) -> str:
‘’‘输入int和float类型,输出string类型’‘’
return a+b
类型注释只能用于标注作者期望的传入数据类型,在传入数据与注释不符时不会报错
# 偏函数partial
作用:截取部分函数/指定函数一部分参数
语法:
```python
square=functools.partial(pow,2)