Python装饰器
装饰器(Decorators)是 Python 的一个重要部分。简单地说:他们是修改其他函数的功能的函数。他们有助于让我们的代码更简短,也更Pythonic(Python范儿)。
出自菜鸟教程
Python函数
函数是将代码封装成代码块可进行重复调用,函数定义如下:
# 函数使用 def 关键字
def test():
print('函数执行体')
test() #函数调用
而装饰器就是装饰函数中函数执行体,增加函数执行体功能丰富性,装饰器代码如下:
#原函数
def test():
print('函数执行体')
#装饰器外壳
def testAdornShell(arg):
#装饰器
def testAdorn():
print('装饰器')
arg()
return testAdorn #返回装饰后的函数
test = testAdornShell(test) #调用装饰器,将返回值重新赋值给test变量
test()
打印结果:
装饰器
函数执行体
学习时出现的疑惑
一、打印报错
- return语句写入内嵌函数(testAdorn)内部而导致后台报错,报错如下:
TypeError: 'NoneType' object is not callable
原因:代码从上往下依次执行,在“test = testAdornShell(test)”这句之前都为函数定义;
当这句执行时,testAdornShell将test函数作为参数执行;
执行步骤如下:
def testAdornShell(arg): #arg = test
def testAdorn(): #testAdorn函数定义,但函数未调用
print('装饰器')
arg()
return testAdorn
#因里面函数未调用,导致return语句未执行,外层函数无返回值,所以函数默认返回None
test = testAdornShell(test) #将函数返回值(None)重新赋值给test
test() #因test变量重新赋值,值并不是函数,所以调用报错
简单来说:
就是外部函数调用执行,内嵌函数定义不执行,导致最终函数返回值为None,因None被赋值给test变量,所以调用报错。
之所以retrun语句写在外函数内可执行,是因为:
- 外函数执行使得内嵌函数定义;
- 外函数执行使得return语句执行,因return语句是在内嵌函数定义后执行,所以函数返回值就是定义好的内嵌函数
二、运行过程到底是怎样的
此问题可联合参考上面问题,下面是对代码执行每一步进行分析,仅供参考:
#第一步test函数定义
def test():
print('函数执行体')
#第二步testAdornShell函数定义
def testAdornShell(arg):
def testAdorn():
print('装饰器')
arg()
return testAdorn
#第三步testAdornShell函数执行并将函数返回值赋值给test
test = testAdornShell(test)
#第四步新函数执行
test()
装饰器“@”的作用
一般写装饰器都需要用到“@”符号,而@符号的作用就是将装饰器函数返回值赋值给需要装饰的函数变量(test = testAdornShell(test) ),加装饰符后代码变化如下:
def testAdornShell(arg):
def testAdorn():
print('装饰器')
arg()
return testAdorn
@testAdornShell
def test():
print('函数执行体')
test()
注:使用“@”符号需要必须先定义装饰器,否则汇报如下错误:
NameError: name ‘testAdornShell’ is not defined