功能子段的Python装饰器

时间:2018-12-01 18:25:21

标签: python decorator python-decorators

在Python中,有没有一种很好的方法将装饰器(或类似的东西)应用于整个函数,而不应用于整个函数体的子段?

我想要的可能看起来像这样:

def deco_double(f):
    def wrapper():
            f()
            f()
    return wrapper

def foo():
    @deco_double:
        print("hello")
        print("stack")
    @deco_double:
        print("overflow")

foo()

执行结果如下:

hello
stack
hello
stack
overflow
overflow

如果解决方案不完全是装饰器,那是可以的,我需要的是一种包装函数子段的方法,但是要采用一种抽象的方式。预先谢谢您:)

修改: 对我来说,仅将其拆分为多个功能是不可行的。我正在开发一个用于程序员的框架,我希望他们以紧凑的方式编写函数(在示例中编写foo()。而且,我实际上在做的事情远不只是重复)

edit2: 到目前为止,看来我别无选择,只能期望框架用户以某种方式声明命名函数...

4 个答案:

答案 0 :(得分:1)

功能体被编译为一个整体运行的单个“代码”对象-更改此代码对象的运行方式,在其中插入内容,这些内容可能与语言代码本身一样复杂(即实际“执行” Python字节码的代码。

因此,执行流程中的任何更改都可以通过使用已经执行该操作的语言中的语句来轻松完成。

如果要在函数体内的各个部分中使用等效的通用装饰器,最简单的方法是将该函数本身细分为内部函数-然后可以应用转换,或多次执行每个部分,只需调用这些函数(甚至直接装饰它们)即可。

但是,在您提出问题的情况下,您可以并且可能应该仅使用简单的旧for循环:

def foo():
    for _ in (0, 1):
        print("hello")
        print("stack")
    for _ in (0, 1):
        print("overflow")

对于我上面写的任意“装饰者行为”,只需使用嵌套函数:

def foo():
    @deco_double
    def part1()
        print("hello")
        print("stack")
    part1()
    @deco_double:
    def part2():
        print("overflow")
    part2()

答案 1 :(得分:0)

您将必须提取foo()的部分功能以分隔功能,然后将装饰器用作功能并调用它。

def deco_double(f):
    def wrapper():
            f()
            f()
    return wrapper

def my_f1():
     print("hello")
     print("stack")

def my_f2():
     print("overflow")

def foo():
    deco_double(my_f1)()
    deco_double(my_f2)()

foo()

答案 2 :(得分:0)

要实现此目的,您可能需要使用lambda传递函数:

def doubler(f):
  f()
  f()

def foo():
  doubler(lambda: print("hello"))

  doubler(lambda: print("world"))

foo()
"hello"
"hello"
"world"
"world"

lambda中将要运行两次的代码包装起来,然后将该函数传递给doubler

答案 3 :(得分:0)

用装饰器@deco_double声明任何名称的两个函数,并在您使用的情况下,在任何其他函数foo()中调用它们,然后简单地调用foo()

def deco_double(f):
    def wrapper():
            f()
            f()
    return wrapper
@deco_double
def func1():
     print("hello")
     print("stack")
@deco_double
def func2():
     print("overflow")
def foo():
    func1()
    func2()
foo()

此代码的输出。

hello
stack
hello
stack
overflow
overflow