理解python装饰器的必需知识

# -*- coding:utf-8 -*-

"""
一切皆对象
"""
def hi(name='mecexia'):
return "hi " + name

print(hi())

# 将一个函数赋值给一个变量
greet = hi # 这里没有使用小括号,因为并不是要调用hi函数,而是要定义一个greet函数,如
print(greet)
print('-----')
print(greet())

# 将一个函数值赋给一个变量
greet1 = hi() # 这里是调用函数,打印如下
print(greet1)
#print(greet1()) # 函数打印,报TypeError

# 如果删掉旧的hi函数,看会发生什么!
del hi
#print(hi()) # 报NameError

# 再打印greet变量看看
print(greet)
print(greet())
print('----')
print(greet1)
# 小结:也就是说,把一个函数赋值给一个变量后,即使删除原函数,被定义的函数仍生效

"""
在函数中定义函数
"""
def hi2(name='mecexia'):
print('now you are inside the hi() function')
def greet2():
return ('now you are in the greet() function')
def welcome2():
return ('now you are in the welcome() function')

print(greet2())
print(welcome2())
print('now you are back in the hi() function')

hi2() # 无论何时调用hi(),greet2(),welcome2()将会同时被调用

# 调用函数中定义的函数看看
print('----')
#greet2() # 报NameError
# 小结:也就是说,在函数中定义的函数,是跟随外层函数调用而调用的,在外部是无法被调用的

"""
从函数中返回函数
"""
def hi3(name='mecexia1'):
def greet3():
return ('now you are in the greet() function')
def welcome3():
return ('now you are in the welcome() function')

if name == 'mecexia':
return greet3
else:
return welcome3
a = hi3()
print(a)
print('=====')
print(a())
print('++++++')
print(hi3()())

# 小结:在函数中返回的函数,如果不带括号,函数就不会被执行,只是赋值

"""
将函数作为参数传给另一个函数
"""
def hi4():
return('hi mece')
def doSomethingBeforeHi(func):
print('I am doing some boring work before executing hi4()')
print(func())

doSomethingBeforeHi(hi4)
# 小结:函数名可以被作为一个参数传递给另一个函数,调用时加上括号即可。
# 现在已具备学习装饰器的必需知识了,装饰器让你在一个函数的前后去执行代码???

"""
你的第一个装饰器
"""
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

def a_function_requiring_decoration():
print('I am the function which needs some decoration to remove my smell')

a_function_requiring_decoration()
print('======')

a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
# 现在a_function_requiring_decoration就被包裹在wrapTheFunction()函数中了
# 调用装饰器函数
a_function_requiring_decoration()
# 小结;这正是python中装饰器做的事情!它们封装一个函数,并且用这样或者那样的方式来修改它的行为。
# 现在你或许疑惑,代码里面并没有使用 @ 符号,那只是用简短的代码生成一个被装饰的函数,这里我们如何使用@来运行之前的代码:

print('--------')
@a_new_decorator
def a_function_requring_decoration1():
"""Hey you! Decorate me!"""
print('a_new_decorator')

a_function_requring_decoration1()
# 小结:@a_new_decorator作为装饰器,来装饰被调函数a_function_requring_decoration1
# 等价于 a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
print('-------')

print(a_function_requring_decoration1.__name__)
# 输出wrapTheFunction,这里的函数被它给替代了。它重写了我们函数的名字和注释文档(docstring)。幸运的是python给我们
# 提供一个简单的函数来解决这个问题,那就是functools.wraps。我们修改上个例子来使用functools.wraps:
print('------')

from functools import wraps
def a_new_decorator2(a_func):
@wraps(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_decorator2
def a_function_requiring_decoration2():
"""Hey yo! Decorate me!"""
print('a_new_decorator2')

print(a_function_requiring_decoration2.__name__)
posted @ 2021-10-26 12:27  ReluStarry  阅读(42)  评论(0编辑  收藏  举报