一个空运行的装饰器

Posted

技术标签:

【中文标题】一个空运行的装饰器【英文标题】:A dry run decorator 【发布时间】:2015-11-02 19:34:33 【问题描述】:

我正在尝试编写一个包装函数的函数装饰器。如果使用dry=True 调用该函数,则该函数应该简单地打印其名称和参数。如果它使用dry=False 调用,或者没有dry 作为参数,它应该可以正常运行。

我有一个玩具:

from functools import wraps
def drywrap(func):

    @wraps(func)
    def dryfunc(*args, **kwargs):
        dry = kwargs.get('dry')
        if dry is not None and dry:
            print("Dry run  with args  ".format(func.func_name, args, kwargs))
        else:
            if dry is not None:
                del kwargs['dry']
            return func(*args, **kwargs)
        return dryfunc

    @drywrap
    def a(something):
#  import pdb; pdb.set_trace()
      print("a")
      print(something)

      a('print no dry')

      a('print me', dry=False)

      a('print me too', dry=True)

...但是当我将它放入我的应用程序时,即使在参数中使用dry=True,打印语句也永远不会运行。我也试过:

from functools import wraps
def drywrap(func):

    @wraps(func)
    def dryfunc(*args, **kwargs):
        def printfunc(*args, **kwargs):
            print("Dry run  with args  ".format(func.func_name,args,kwargs))   
            dry = kwargs.get('dry')
            if dry is not None and dry:
                return printfunc(*args, **kwargs)
            else:
                if dry is not None:
                    del kwargs['dry']
                return func(*args, **kwargs)
            return dryfunc

我应该注意,作为我的应用程序的一部分,drywrap 函数是在使用之前导入的 utils 文件的一部分...

src/build/utils.py  <--- has drywrap

src/build/build.py
src/build/plugins/subclass_build.py   <--- use drywrap via "from build.utils import drywrap"

【问题讨论】:

我认为这里有些缩进搞砸了 请很好地缩进。 “为我工作”使用您的代码(并在修复缩进之后)。 @SteveJessop 让我头疼。 添加了 from functools。对缩进表示歉意;我从一个工作代码示例中复制粘贴,并没有注意到粘贴时有任何缩进错误。 【参考方案1】:

以下 github 项目提供了“一个有用的 python 干运行装饰器”,它允许检查“我们程序的基本逻辑,而无需运行某些冗长且会导致副作用的操作。”

见https://github.com/haarcuba/dryable

【讨论】:

【参考方案2】:

这感觉像是一个解决方案。

def drier(dry=False):
    def wrapper(func):

        def inner_wrapper(*arg,**kwargs):
            if dry:
                print(func.__name__)
                print(arg)
                print(kwargs)
            else:
                return func(*arg,**kwargs)
        return inner_wrapper
    return wrapper

@drier(True)
def test(name):
    print("hello "+name)

test("girish")

@drier()
def test2(name,last):
   print("hello  ".format(name,last))

但是正如您所看到的,即使您没有任何参数,您也必须提供 @drier() 而不是 @drier

注意:使用 python 3.4.1

【讨论】:

以上是关于一个空运行的装饰器的主要内容,如果未能解决你的问题,请参考以下文章

Go语言之装饰器

函数和装饰器

Python 装饰器:在测试前运行装饰器

装饰器

python装饰器

python-闭包和装饰器-02-装饰器(decorator)