装饰器就是一个闭包,无非就是接收了一个函数作为参数
首先,在python中函数也可以作为参数进行传递,如下面例子
def f1(x):
return x
def f2(f, x):
print(f(4))
print(x)
f2(f1, 1)
# 运行结果
4
1
这里f2接收的第一个参数传递的就是函数f1,也正常的运行了
闭包个人理解就是在一个函数内嵌套一个函数
def f1():
def f2():
return "嵌套"
return f2
y = f1()
print(y())
# 运行结果
嵌套
个人理解就是调用了f1,返回了f2,y()就相当于f2()返回“嵌套”
装饰器
def f(func):
def wrapper():
pass
return wrapper
目前见到的差不多是上面的定义
但是也不是非要写成wrapper,例如下面的例子
# 装饰器
import time
def time_1(f):
def w(*args):
t1 = time.time()
print("time{}".format(t1))
y = f(*args)
t2 = time.time()
print("time{}".format(t2))
return y
return w
@time_1
def fun2(x, y): # fun2 = time_1(fun2)
z = x + y
return z
x = fun2
print(x(7,8))
# 运行结果
time1668260178.1578946
time1668260178.1578946
15
首先下面这一段
@time_1
def fun2(x, y): # fun2 = time_1(fun2)
z = x + y
return z
这里fun2 相当于time_1(fun2),time_1接收fun2这个参数,返回的是w这个函数,fun2现在就是w,所以x = f(7,8)就是w(7,8)
def w(*args):
t1 = time.time()
print("time{}".format(t1))
y = f(*args)
t2 = time.time()
print("time{}".format(t2))
return y
return w
w(7,8)执行的是上面的代码块,先得到t1并打印
y = f(*args)
这里f就是time_1(fun2)中接收的fun2,所以f(*args)就是fun2(*args),即z = 7+8
接着得到t2并打印,然后返回y的值
# 装饰器
def time_1(f):
def w(x, y):
z = f(x,y)
print(z)
return w
def time_2(f):
def m():
print("cheng gong")
f(1, 4)
return m
@time_2
@time_1
def fun2(x, y): # fun2 = time_2(time_1(fun_2)) = time_2(w)
z = x + y
return z
x = fun2
x()
# 运行结果
cheng gong
5
对于下面的代码等价于fun2 = time_2(time_1(fun2))
@time_2
@time_1
def fun2(x, y): # fun2 = time_2(time_1(fun_2))
z = x + y
return z
time_1接收参数fun2返回其中的w,所以变为了fun2 = time_2(w)
time_2接收参数返回m,所以就变为了fun2 = m
所以 x()就是m(),执行m这个函数,首先打印"cheng gong" 其中的
f(1,4)就是w(1,4),所以接下来执行w这个函数,z = f(1,4)就是fun2(1,4),得到z= 5,接下来打印5
class A():
def a1(self,x):
return 2*x
class B(A):
def a1(self,x):
super().a1(x)
b = B()
y=b.a1(1)
print(y)
#运行结果
None
这里我个人的理解是只是调用了父类的方法,但是没返回值,如果想要返回父类中计算的值
改成下面的就能得到想要的结果了,个人觉得很像闭包
class B(A):
def a1(self, x):
return super().a1(x)
对于-> 为函数添加元数据,描述函数的返回类型
冒号在变量后面也是起到注解的作用,提示你这个变量应该是什么类型的
def Csy(x:int = 3.1)->int:
return x+0.1
print(Csy(1.1))
# 运行结果
1.2000000000000002
x:int = 3.1 ,说明x应该输入的类型为int,后面的等号是赋为默认值3.1,他只是提示int,但是不一定要遵守。python中整数可以用二进制精确表示
小数确不一定,所以输出结果会出现一点问题
在类中,个人理解可以先不赋值,先给属性安排个类型,像下面这样
class A:
a:float
if __name__ == "__main__":
这一句的作用并不是说从这个位置开始执行,如果在本模块中运行则__name__的值是__main__ ,就会执行这个if的内容,如果在其他脚本中调用这个模块,则__name__等于这个模块的名,就不会运行if中的内容