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
superbai
V2EX  ›  Python

Python 装饰器使用场景疑问

  •  
  •   superbai · 2019-08-06 17:06:49 +08:00 · 1998 次点击
    这是一个创建于 1920 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景:一个脚本里有 2 个函数,里面都执行了比较危险的操作(删除数据),所以我想在执行前加一个确认的动作。打算用装饰器来实现,但是把装饰器加到 2 个函数上之后,执行一个函数需要确认两次...网上搜索了下,装饰器不是随着函数调用执行的。所以这种问题应该用装饰器解决么,还是我使用的姿势不对? 样例代码:

    def confirm(func):
    	def wrapper():
        	# do confirm action
            return func
        return wrapper()
        
    
    @confirm
    def delete_1():
    	# do something
    
    
    @confirm
    def delete_2():
    	# do something
        
        
    if __name__ == '__main__':
    	delete_1()
    

    这种场景下,confirm action 会执行两次

    11 条回复    2019-08-07 12:58:22 +08:00
    fzzff
        1
    fzzff  
       2019-08-06 17:15:33 +08:00   ❤️ 1
    装饰器最终返回一个函数引用,你的返回值就不对
    Tracy1997
        2
    Tracy1997  
       2019-08-06 17:20:59 +08:00   ❤️ 1
    return wrapper
    Takamine
        3
    Takamine  
       2019-08-06 17:23:19 +08:00
    感觉用切面做这个感觉不太合适还是在这两个方法前面再抽一层出来做确认功能吧。
    Takamine
        4
    Takamine  
       2019-08-06 17:27:13 +08:00   ❤️ 1
    @Takamine 直接把要运行的函数当参数丢进去。
    superbai
        5
    superbai  
    OP
       2019-08-06 17:30:48 +08:00
    @fzzff #1
    @Tracy1997 #2 感谢,已经可以了~~太粗心了
    superbai
        6
    superbai  
    OP
       2019-08-06 17:31:02 +08:00
    @Takamine #4 那感觉和装饰器一样....?
    frostming
        7
    frostming  
       2019-08-06 17:32:16 +08:00   ❤️ 1
    def confirm(func):
    def wrapper():
    # do confirm action
    return func()
    return wrapper

    你装饰器的返回搞错了
    sikariba
        8
    sikariba  
       2019-08-06 17:34:27 +08:00   ❤️ 1
    def confirm(func):
    def wrapper():
    user_input = input('yes or no?')
    if user_input == 'yes':
    return func()
    return wrapper


    @confirm
    def delete_1():
    print('delete 1')


    @confirm
    def delete_2():
    print('delete 2')


    if __name__ == '__main__':
    delete_1()
    Takamine
        9
    Takamine  
       2019-08-06 17:43:11 +08:00
    @superbai 嗯阿,实现上差不多,只是自己拿业务做个代理,不用注解,呸,装饰器。
    vkhsyj
        10
    vkhsyj  
       2019-08-06 18:06:11 +08:00   ❤️ 1
    装饰器应该返回的是装饰函数,也就是你的 wrapper, 你这样返回 wrapper()的结果, 等于在脚本运行时就会需要确认,而不是在你函数调用时确认了
    superbai
        11
    superbai  
    OP
       2019-08-07 12:58:22 +08:00
    @Takamine #9 哈哈,我也是总想着注解,写装饰器写起来不太适应😂
    @vkhsyj #10 感谢,对装饰器理解不深,搞错了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5366 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 07:36 · PVG 15:36 · LAX 23:36 · JFK 02:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.