此系列文档:
本文目录:
- 一、装饰器基础(什么是装饰器)
一、装饰器基础(什么是装饰器)
Python的函数是对象
要了解装饰器,您必须首先了解函数是Python中的对象。这具有重要的联系。
让我们来看一个简单的例子:
def shout(word="yes"): return word.capitalize()+"!" print(shout()) # 输出 : 'Yes!' # 作为一个对象,您可以像其他对象一样将函数赋给变量 scream = shout #注意我们不使用括号:我们没有调用函数 #我们将函数“shout”放入变量“scream”。 #这意味着您可以从“scream”中调用“shout”: print(scream()) # 输出: 'Yes!' #除此之外,这意味着您可以删除旧名称'shout',该功能仍可从'scream'访问 del shout try: print(shout()) except NameError as e: print(e) #输出: "name 'shout' is not defined" print(scream()) # 输出: 'Yes!'
请记住这一点,我们将在不久后回头再说。
Python函数的另一个有趣特性是可以在另一个函数中定义它们!
def talk(): # 您可以在“talk”中动态定义一个函数... def whisper(word="yes"): return word.lower()+"..." # ...并且可以立马使用它。 print(whisper()) #您每次调用“talk”,都会定义“whisper”,然后在“talk”中调用“whisper”。 talk() # 输出: # "yes..." # 但是"whisper"不存在"talk"定义以外的地方: try: print(whisper()) except NameError as e: print(e) #输出 : "name 'whisper' is not defined"
函数参考
OK,应该还在看吧?现在开始有趣的部分...
您已经看到函数是对象。 因此,函数:
- 可以分配给变量
- 可以在另一个函数中定义
这意味着
一个函数可以 return
另一个功能
。
def getTalk(kind="shout"): # 我们顶一个即时的函数 def shout(word="yes"): return word.capitalize()+"!" def whisper(word="yes") : return word.lower()+"..."; # 然后我们返回它 if kind == "shout": #我们不使用“()”,所以我们没有调用函数,我们正在返回这个函数对象 return shout else: return whisper #获取函数并将其分配给变量: "talk" talk = getTalk() #您可以看到“talk”是一个函数对象: print(talk) #输出 : <function shout at 0xb7ea817c> #函数对象返回的内容: print(talk()) #输出 : Yes! #如果您感到困惑,甚至可以直接使用它: print(getTalk("whisper")()) #outputs : yes...
还有更多的内容!
如果可以 return
一个函数,则可以将其中一个作为参数传递:
def doSomethingBefore(func): print("I do something before then I call the function you gave me") print(func()) doSomethingBefore(scream) #输出: #I do something before then I call the function you gave me #Yes!
好吧,您只具备了解装饰器所需的所有信息。 您会看到,装饰器是“包装器(wrappers)”,这意味着 它们使您可以在装饰函数之前和之后执行代码, 而无需修改函数本身的代码内容。
手工进行装饰
您将知道如何进行手动操作:
#装饰器是讲另外一个函数作为参数的函数 def my_shiny_new_decorator(a_function_to_decorate): # 在内部,装饰器动态定义一个函数:包装器(wrappers)。 # 此功能将被包装在原始功能的外部,以便它可以在代码之前和之后执行代码。 def the_wrapper_around_the_original_function(): # 在调用原始函数之前,将要执行的代码放在此处 print("Before the function runs") #在此处调用函数(使用括号) a_function_to_decorate() # 在调用原始函数后,将要执行的代码放在此处 print("After the function runs") #至此,“a_function_to_decorate”从未执行过。 #我们返回刚刚创建的包装函数。 #包装器包含函数和在代码之前和之后执行的代码。随时可以使用! return the_wrapper_around_the_original_function #现在,假设您创建了函数,但是不想再修改的函数。 def a_stand_alone_function(): print("I am a stand alone function, don't you dare modify me") a_stand_alone_function() #输出: I am a stand alone function, don't you dare modify me #所以,您可以装饰它以扩展其行为。 #只需将其传递给装饰器,它将动态地包装在 #您想要的任何代码中,并为您返回准备使用的新功能: a_stand_alone_function_decorated = my_shiny_new_decorator(a_stand_alone_function) a_stand_alone_function_decorated() #输出: #Before the function runs #I am a stand alone function, don't you dare modify me #After the function runs
现在,您可能希望每次调用 a_stand_alone_function
时 a_stand_alone_function_decorated
都调用它。
这很简单,只需 a_stand_alone_function
用以下方法返回的函数覆盖 my_shiny_new_decorator
:
a_stand_alone_function = my_shiny_new_decorator(a_stand_alone_function) a_stand_alone_function() #输出: #Before the function runs #I am a stand alone function, don't you dare modify me #After the function runs #这正是装饰器的工作!
装饰器神秘化
这里展示一下使用装饰器的语法:
@my_shiny_new_decorator def another_stand_alone_function(): print("Leave me alone") another_stand_alone_function() #输出: #Before the function runs #Leave me alone #After the function runs
是的,仅此而已。 @decorator
只是实现以下目的的捷径:
another_stand_alone_function = my_shiny_new_decorator(another_stand_alone_function)
装饰器只是 装饰器设计模式 的pythonic变体。 Python中嵌入了几种经典的 设计模式 来简化开发(例如迭代器)。
当然,您可以累加装饰器:
def bread(func): def wrapper(): print("</''''''\>") func() print("<\______/>") return wrapper def ingredients(func): def wrapper(): print("#tomatoes#") func() print("~salad~") return wrapper def sandwich(food="--ham--"): print(food) sandwich() #输出: --ham-- sandwich = bread(ingredients(sandwich)) sandwich() #输出: #</''''''\> # #tomatoes# # --ham-- # ~salad~ #<\______/>
使用Python装饰器语法:
@bread @ingredients def sandwich(food="--ham--"): print(food) sandwich() #outputs: #</''''''\> # #tomatoes# # --ham-- # ~salad~ #<\______/>
您设置装饰器事项的顺序是很重要的,如::
@ingredients @bread def strange_sandwich(food="--ham--"): print(food) strange_sandwich() #outputs: ##tomatoes# #</''''''\> # --ham-- #<\______/> # ~salad~
以上所述就是小编给大家介绍的《[python用法] 我终于弄懂了Python的装饰器(一)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。