想请教一下 python 装饰器的作用 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
SlipStupig
V2EX    Python

想请教一下 python 装饰器的作用

  •  
  •   SlipStupig 2016-08-08 19:07:51 +08:00 4937 次点击
    这是一个创建于 3362 天前的主题,其中的信息可能已经有所发展或是发生改变。
    之前理解 python 装饰器等于是在函数执行前先执行装饰器函数,但是直接写一个函数调用或者写回调函数比有什么区别呢?
    第 1 条附言    2016-08-11 12:08:29 +08:00
    感谢各位回答,我总结了一下大家的意见
    1.减少函数嵌入
    2.函数前置拦截
    3.提高代码可读性
    22 条回复    2016-08-09 14:07:52 +08:00
    Cabana
        1
    Cabana  
       2016-08-08 19:13:04 +08:00 via Android
    能写在一行里(逃…
    greenlet
        2
    greenlet  
       2016-08-08 19:22:49 +08:00
    功能上没区别,看上去更自然。
    lixm
        3
    lixm  
       2016-08-08 19:27:01 +08:00
    AOP
    justou
        4
    justou  
      &bsp;2016-08-08 19:30:00 +08:00
    装饰器模式的好处
    mgna17
        5
    mgna17  
       2016-08-08 19:30:34 +08:00 via Android
    先后顺序的差别吧,装饰器总是比被装饰函数先执行,它可以决定如何使用被装饰函数。
    wizardforcel
        6
    wizardforcel  
       2016-08-08 19:38:28 +08:00
    是在函数定义后以函数作为参数执行装饰器函数,返回值还绑定到原来的名字上。
    justou
        7
    justou  
       2016-08-08 19:41:10 +08:00   1
    我在实际当中使用过的一个情形:
    有一大批函数都需要做相同或相似的参数检查, 每个函数里面都检查会造成大量重复代码, 那么就把检查部分提出来放到一个检查函数, 而这个检查函数返回的是经过参数检查的一系列函数, 也就是函数返回函数, python 里自然就是装饰器了, 只需要在那一系列函数上方套一个 @check_func, 调用这一系列函数就自动完成参数检查了: 避免了重复代码, 避免了到处都要手动调用一个检查函数
    am241
        8
    am241  
       2016-08-08 20:01:22 +08:00 via Android
    为了思路清晰
    lichun
        9
    lichun  
       2016-08-08 21:57:47 +08:00
    完全可以把 "@" 当做语法糖,也可以直接使用函数式写法。只不过那样不便于代码维护
    xrlin
        10
    xrlin  
       2016-08-08 22:01:33 +08:00
    方便进行维护,而且程序更清晰,很方便给其他函数添加额外的功能。
    murmur
        11
    murmur  
       2016-08-08 22:05:55 +08:00
    如果能用装饰器上的功能 需要的时候 去掉装饰器一样很容易
    Yinz
        12
    Yinz  
       2016-08-08 22:06:22 +08:00
    『装饰器等于是在函数执行前先执行装饰器函数』这句话其实有点问题。
    想象这样一个情形,一个外部 python 文件(a.py)中,包含了一个被装饰器(dec)修饰的函数(some_func)。当你在其他文件(b.py)中 import a ,装饰器函数(dec)就被执行了。而不是你调用 some_func 时才执行 dec 。你可以试一下在 dec 中写一句 print ,然后就可以看到 import a 的时候就被 print 出来了。
    julyclyde
        13
    julyclyde  
       2016-08-08 22:25:53 +08:00
    不是执行函数前先执行装饰器
    而是在声明函数时先执行装饰器,然后用装饰器输出的那个函数体代替原来准备声明的那个函数体
    incompatible
        14
    incompatible  
       2016-08-08 22:30:47 +08:00 via Android
    关键词: AOP
    通常用来实现:记录业务日志、做参数统一检验、做事务管理
    tongjie
        15
    tongjie  
       2016-08-08 22:49:09 +08:00
    def safe_run(_logger):
    def _run_once(func):
    def f(*args,**kwargs):
    try:
    return func(*args,**kwargs)
    except:
    _logger.error(traceback.format_exc())
    return f
    return _run_once

    在要执行的方法前面加上这个装饰器,放心多了;
    BOYPT
        16
    BOYPT  
       2016-08-08 23:18:23 +08:00
    你们说那么多,还不如看看 flask 或者 bottle 框架是怎么用的,瞬间明白装饰器的好处了。
    will0404
        17
    will0404  
       2016-08-08 23:30:29 +08:00 via iPhone
    只是好看一点罢了 和写在函数里调用返回个函数没什么区别 类似蛋疼的 feature 还有 js 里的 promise 大张旗鼓的被实现出来实际呢只是让嵌套回调好看一点 个人灼见
    SayHaHa
        18
    SayHaHa  
       2016-08-09 00:57:46 +08:00
    语法糖,复用方便
    hosiet
        19
    hosiet  
       2016-08-09 08:59:18 +08:00 via Android
    14 楼的用法基本就是九成的使用场景,只要写一次装饰器就可以到处使用,概念清晰易理解,何乐而不为呢
    xiaket
        20
    xiaket  
       2016-08-09 09:15:08 +08:00
    readability counts.
    ziXiong
        21
    ziXiong  
       2016-08-09 13:09:23 +08:00
    代码重用,也可以完全改变被装饰函数的行为。很灵活的。
    zhujq
        22
    zhujq  
       2016-08-09 14:07:52 +08:00
    用上比不用上更能装逼
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3965 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 10:14 PVG 18:14 LAX 03:14 JFK 06:14
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86