Python装饰器Decorators
阅读原文时间:2023年07月09日阅读:2

def hi(name="yasoob"):
return "hi " + name
print(hi())

我们甚至可以将一个函数赋值给一个变量,比如

greet=hi

我们这里没有在使用小括号,因为我们并不是在调用hi函数

而是在将它放在greet变量里头。我们尝试运行下这个

print(greet(),greet,sep='\n')
gre=hi()
print(gre)
'''
以上输出为:
hi yasoob
hi yasoob

hi yasoob
'''

如果我们删掉旧的hi函数,看看会发生什么!

del hi

print(hi())

outputs: NameError

print(greet())

outputs: 'hi yasoob'

全部输出为:
'''
hi yasoob
hi yasoob

hi yasoob
hi yasoob
'''

参考:https://www.runoob.com/w3cnote/python-func-decorators.html

在函数中定义函数

刚才那些就是函数的基本知识了。我们来让你的知识更进一步。在 Python 中我们可以在一个函数中定义另一个函数:

def hi(name="yasoob"):
print("now you are inside the hi() function")

def greet1():  
    return "now you are in the greet1() function"

def welcome():  
    return "now you are in the welcome() function"

print(greet1())  
print(welcome())  
print("now you are back in the hi() function")

print(hi())

output:now you are inside the hi() function

now you are in the greet1() function

now you are in the welcome() function

now you are back in the hi() function

None

上面展示了无论何时你调用hi(), greet1()和welcome()将会同时被调用。

然后greet1()和welcome()函数在hi()函数之外是不能访问的,比如:

greet1()

outputs: NameError: name 'greet1' is not defined

那现在我们知道了可以在函数中定义另外的函数。也就是说:我们可以创建嵌套的函数。现在你需要再多学一点,就是函数也能返回函数。  

从函数中返回函数

其实并不需要在一个函数里去执行另一个函数,我们也可以将其作为输出返回出来:

def hi(name="yasoob"):
def greet1():
return "now you are in the greet1() function"

def welcome():  
    return "now you are in the welcome() function"

if name == "yasoob":  
    return greet1  
else:  
    return welcome

a = hi()
print(a)
#outputs:

#上面清晰地展示了`a`现在指向到hi()函数中的greet1()函数
#现在试试这个

print(a())
#outputs: now you are in the greet1() function

再次看看这个代码。在 if/else 语句中我们返回 greet 和 welcome,而不是 greet() 和 welcome()。为什么那样?这是因为当你把一对小括号放在后面,这个函数就会执行;然而如果你不放括号在它后面,那它可以被到处传递,并且可以赋值给别的变量而不去执行它。 你明白了吗?让我再稍微多解释点细节。

当我们写下 a = hi(),hi() 会被执行,而由于 name 参数默认是 yasoob,所以函数 greet 被返回了。如果我们把语句改为 a = hi(name = "ali"),那么 welcome 函数将被返回。我们还可以打印出hi()(),这会输出 now you are in the greet() function

def hi(name="yasoob"):
def greet1():
return "now you are in the greet1() function"

def welcome():  
    return "now you are in the welcome() function"

if name == "yasoob":  
    return greet1  
else:  
    return welcome

a = hi()
print(a,hi()(),sep='\n')

输出为:
.greet1 at 0x00000240E0EAAAF0>
now you are in the greet1() function

将函数作为参数传给另一个函数

def hi():
return "hi yasoob!"

def doSomethingBeforeHi(func):
print("I am doing some boring work before executing hi()")
print(func())

doSomethingBeforeHi(hi)
#outputs:I am doing some boring work before executing hi()

hi yasoob!

现在你已经具备所有必需知识,来进一步学习装饰器真正是什么了。装饰器让你在一个函数的前后去执行代码。

你的第一个装饰器

在上一个例子里,其实我们已经创建了一个装饰器!现在我们修改下上一个装饰器,并编写一个稍微更有用点的程序:

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 foul smell")

a_function_requiring_decoration()
#outputs: "I am the function which needs some decoration to remove my foul smell"

a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
#now a_function_requiring_decoration is wrapped by wrapTheFunction()

a_function_requiring_decoration()
#outputs:I am doing some boring work before executing a_func()

I am the function which needs some decoration to remove my foul smell

I am doing some boring work after executing a_func()

你看明白了吗?我们刚刚应用了之前学习到的原理。这正是 python 中装饰器做的事情!它们封装一个函数,并且用这样或者那样的方式来修改它的行为。

现在你也许疑惑,我们在代码里并没有使用 @ 符号?那只是一个简短的方式来生成一个被装饰的函数。这里是我们如何使用 @ 来运行之前的代码:  

@a_new_decorator
def a_function_requiring_decoration():
"""Hey you! Decorate me!"""
print("I am the function which needs some decoration to "
"remove my foul smell")

a_function_requiring_decoration()
#outputs: I am doing some boring work before executing a_func()

I am the function which needs some decoration to remove my foul smell

I am doing some boring work after executing a_func()

#the @a_new_decorator is just a short way of saying:
a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器