首页 炼丹房 帖子详情
python装饰器入门
收藏
快速回复
炼丹房 问答新手上路 2754 23
python装饰器入门
收藏
快速回复
炼丹房 问答新手上路 2754 23

装饰器,说白了就是定义其他函数调用之前或之后需要执行的通用代码,可作用于其他任何函数,提高代码复用度。

0
收藏
回复
全部评论(23)
时间顺序
水水水的老师
#2 回复于2020-04

>>> def deco(func):
... def inner():
... print('running inner()')
... return inner ➊
...
>>> @deco
... def target(): ➋
... print('running target()')
...
>>> target() ➌
running inner()
>>> target ➍
.inner at 0x10063b598>

➊ deco 返回 inner 函数对象。
➋ 使用 deco 装饰 target。
➌ 调用被装饰的 target 其实会运行 inner。
➍ 审查对象,发现 target 现在是 inner 的引用。

0
回复
水水水的老师
#3 回复于2020-04

严格来说,装饰器只是语法糖。如前所示,装饰器可以像常规的可调用对象那样调用,其参数是另一个函数。有时,这样做更方便,尤其是做元编程(在运行时改变程序的行为)时。 综上,装饰器的一大特性是,能把被装饰的函数替换成其他函数。第二个特性是,装饰器在加载模块时立即执行。

0
回复
水水水的老师
#4 回复于2020-04

装饰器有个特点   它们在被装饰的函数定义之后立即运行

通常是在导入时(即 Python 加载模块时)Python执行装饰器

0
回复
水水水的老师
#5 回复于2020-04
装饰器有个特点   它们在被装饰的函数定义之后立即运行 通常是在导入时(即 Python 加载模块时)Python执行装饰器

registry = [] ➊
def register(func): ➋
    print('running register(%s)' % func) ➌
    registry.append(func) ➍
    return func ➎
@register ➏
def f1():
    print('running f1()')
@register
def f2():
    print('running f2()')
def f3(): ➐
    print('running f3()')
def main(): ➑
    print('running main()')
    print('registry ->', registry)
    f1()
    f2()
    f3()
if __name__=='__main__':
    main() ➒

0
回复
水水水的老师
#6 回复于2020-04
registry = [] ➊ def register(func): ➋     print('running register(%s)' % func) ➌     registry.append(func) ➍     return func ➎ @register ➏ def f1():     print('running f1()') @register def f2():     print('running f2()') def f3(): ➐     print('running f3()') def main(): ➑     print('running main()')     print('registry ->', registry)     f1()     f2()     f3() if __name__=='__main__':     main() ➒
展开

➊ registry 保存被 @register 装饰的函数引用。
➋ register 的参数是一个函数。
➌ 为了演示,显示被装饰的函数。
➍ 把 func 存入 registry。
➎ 返回 func:必须返回函数;这里返回的函数与通过参数传入的一样。
➏ f1 和 f2 被 @register 装饰。
➐ f3 没有装饰。
➑ main 显示 registry,然后调用 f1()、f2() 和 f3()。
➒ 只有把 registration.py 当作脚本运行时才调用 main()。

0
回复
水水水的老师
#7 回复于2020-04
registry = [] ➊ def register(func): ➋     print('running register(%s)' % func) ➌     registry.append(func) ➍     return func ➎ @register ➏ def f1():     print('running f1()') @register def f2():     print('running f2()') def f3(): ➐     print('running f3()') def main(): ➑     print('running main()')     print('registry ->', registry)     f1()     f2()     f3() if __name__=='__main__':     main() ➒
展开

把 registration.py 当作脚本运行得到的输出如下:
$ python3 registration.py
running register()
running register()
running main()
registry -> [, ]
running f1()
running f2()
running f3()

0
回复
AIStudio810258
#8 回复于2020-04

做大型的项目呢吧,研究的都是语言的动态功能。

0
回复
AIStudio810258
#9 回复于2020-04

这个跟CSS的装饰器看起来一个意思。都属于一整一大片,全部向前看。

0
回复
AIStudio810258
#10 回复于2020-04

我是用python时需要用到什么,就现去搞明白。

大佬,这个装饰器有“层叠”的性质么?能像金字塔式嵌套么?

0
回复
MLTcola
#11 回复于2020-04

紧跟大佬

0
回复
水水水的老师
#12 回复于2020-04
做大型的项目呢吧,研究的都是语言的动态功能。

哈哈   各种设计模式

0
回复
水水水的老师
#13 回复于2020-04
做大型的项目呢吧,研究的都是语言的动态功能。

刚做完一个策略模式的PPT

0
回复
水水水的老师
#14 回复于2020-04
MLTcola #11
紧跟大佬

不敢当不敢当

0
回复
水水水的老师
#15 回复于2020-04
我是用python时需要用到什么,就现去搞明白。 大佬,这个装饰器有“层叠”的性质么?能像金字塔式嵌套么?

哈哈  看来你对这门语言还有待深入呀

0
回复
水水水的老师
#16 回复于2020-04
这个跟CSS的装饰器看起来一个意思。都属于一整一大片,全部向前看。

这个不太一样吧

0
回复
水水水的老师
#17 回复于2020-04
这个跟CSS的装饰器看起来一个意思。都属于一整一大片,全部向前看。

CSS的装饰器和我这里说的应该是两回事

0
回复
AIStudio810258
#18 回复于2020-04
哈哈  看来你对这门语言还有待深入呀

仔细看看,明白了。@就是个语法糖,用来简写的。这个功能一般是用于在各个模块加日志记录、登录确认之类功能的。

0
回复
水水水的老师
#19 回复于2020-04
仔细看看,明白了。@就是个语法糖,用来简写的。这个功能一般是用于在各个模块加日志记录、登录确认之类功能的。

可以这样理解

0
回复
g
gbsrept
#20 回复于2020-06

修改了一下,再说的透彻一些:

Python 2.7.16 (v2.7.16:413a49145e, Mar  4 2019, 01:37:19) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> registry = []
>>> def register(func):
...     print('--> register(%s)' % func)
...     registry.append(func)
...     def new_func():
...         print('call> register(%s)' % func)
...         func()
...     return new_func
...
>>> @register
... def f1():
...     print('running f1()')
...
--> register()
>>> @register
... def f2():
...     print('running f2()')
...
--> register()
>>> def f3():
...     print('running f3()')
...
>>> def main():
...     print('running main()')
...     print('registry ->', registry)
...     f1()
...     f2()
...     f3()
...
>>> main()
running main()
('registry ->', [, ])
call> register()
running f1()
call> register()
running f2()
running f3()
>>>
>>>
0
回复
g
gbsrept
#21 回复于2020-06

编辑器不给力,发个截图吧。

0
回复
在@后输入用户全名并按空格结束,可艾特全站任一用户