避坑指南:51单片机读写AT24C02 EEPROM时,I2C时序那些容易出错的细节
2026/6/15 2:56:53
首先回顾一下前面学过的函数:
def hi(name='yasoob'): return 'hi ' + name greet = hi print(greet())在python中,一切皆对象
#方法一、 def a(name = 'youzi'): print('youzi') def greet(): return 'now greet() function' def welcome(): return 'now welcome() function' print(greet()) print(welcome()) print('now a() function') hi() #方法二、 #这里如果也可以写成: def a(name='youzi'): def greet(): return 'now greet() function' def welcome(): return 'now welcome() function' if name == 'youzi': return greet else: return welcome num = a(name='ddd') num1 = a(name='youzi') print(num()) print(num1())这里解释方法二细节:
函数里面的函数,如果没有调用就不会被执行,只有调用的时候才会执行
函数里面的函数只能在函数里面的函数调用,不能在函数的外部调用
从函数中返回函数,其实就是调用函数
变量也可以接收函数,但是函数一般分别两种,一种是带括号的叫调用函数并且执行,另一种是不带括号的叫对象
#定义一个函数名叫hi def hi(): #返回的是hi yasoob return 'hi yasoob' #定义一个函数,但是因为我们今天要讲的是装饰器,所以func这个的作用其实是用来接收函数的,当然也可以接收变量、字典、列表参数等 def doSomethingBeforeHi(func): print('I am doing some boring work before executing hi()') a = func() #这个其实是调用我们传过来的函数,因为加了括号 print(a) doSomethingBeforeHi(hi)双层嵌套函数,并且调用另一个函数
def a_new_decorator(a_func): def wrapTheFunction(): print("I am doing some boring work before executing a_func()") #调用传递过来的函数 a_func() print("I am doing some boring work after executing a_func()") #这个return的作用在于触发函数,并且调用函数 return wrapTheFunction def a_function_requiring_decoration(): print("I am the function which needs some decoration to remove my foul smell") a_function_requiring_decoration() #print(a_new_decorator(a_function_requiring_decoration)) a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration) a_function_requiring_decoration()可以函数里面定义函数,当然也可以相互传递函数,函数的参数也可以接收函数
接下来,开始进装饰器,这个时候讲装饰器就会好理解点,博客当时学这个也是很头大,不知道为什么这样做?后面发现之后,感觉还挺有意思的
这里先提前解释:
在装饰函数的时候,其实就已经做了一个动作,就是把下面的函数名,传给了装饰的函数(定义的装饰函数),如果不理解接着往下看
演示
def a_new_decorator(a_func): def wrapTheFunction(): print("I am doing some boring work before executing a_func()") a_func() print("I am doing some boring work after executing a_func()") return wrapTheFunction @a_new_decorator def a_function_requiring_decoration(): print("I am the function which needs some decoration to remove my foul smell") #把a_function_requiring_decoration放到a_new_decorator装饰,但是装饰不会调用 a_new_decorator(a_function_requiring_decoration) a_function_requiring_decoration()def a_new_decorator(a_func): def wrapTheFunction(): print("I am doing some boring work before executing a_func()") a_func() print("I am doing some boring work after executing a_func()") return wrapTheFunction @a_new_decorator def a_function_requiring_decoration(): print("I am the function which needs some decoration to remove my foul smell") print(a_function_requiring_decoration.__name__) >>wrapTheFunction 封装函数 >>这里我们想打印原函数的名字,所以接下来我们需要使用@wraps使用wraps来保持原函数的名字
#从functools库导入函数 from functools import wraps #定义一个函数,添加一个参数f,用来接收函数 def decorator_name(f): #让原函数保持不变 @wraps(f) #这个是语法规范,参数是固定死的,函数名不是,可以随便改,但是要符合命名规范 def decorated(*args,**kwargs): #判断can_run,如果是True就不执行,是false就执行 if not can_run: return "Functions will not run" #把原函数的参数和输入的内容都返回回去 return f(*args,**kwargs) #返回decorated,作用是调用并执行函数 return decorated #使用装饰器 @decorator_name def func(): return ("Functions is running") can_run = True print(func()) can_run = False print(func())return func(*args,**kwargs) 的核心作用:
动态调用函数:func可以是任何函数
传递所有参数:*args传递所有位置参数,也就是元组,**kwargs传递所有关键字参数,也就是字典
保持透明性:装饰器不需要知道被装饰函数的具体函数
返回结果:将原始函数的返回值原样返回
再说一个知识点,那就是闭包
解释:通俗来说,闭包就是函数及其周边环境的组合。(在本文语境下,你可以暂时理解周边环境就是一些外部的变量)
闭包通常涉及到一个内部函数,内部函数可以访问或者说记住外部函数的局部变量,即使外部函数已经执行完毕。
代码如下:
# 创建一个装饰器,名为simple_decorator,里面func可以理解为参数也是函数 def simple_decorator(func): def wrapper(): print("--------开始-------") func() print("--------结束-------") #触发wrapper,也就是调用该函数 return wrapper def greet(): print("您好!") closure = simple_decorator(greet) print(type(closure))closure就是一个闭包的案例!
print("--------开始-------") func() print("--------结束-------") 本质上执行的函数代码 print("--------开始-------") greet() print("--------结束-------")