Python:仅在本地装饰函数的最佳方法

时间:2017-03-29 14:51:13

标签: python python-decorators

装饰函数的最佳方法是什么,但仅限于本地范围。例如,我们有以下内容:

def a():
    do stuff
    b()
    do stuff

我想创建一个函数c()来执行相同的stuff但是装饰b所以它会添加一些额外的东西。我找到了一种方法,但它在全局范围内改变了b():

def c():
    global b
    b = decorator(b)
    a()

有没有办法做到这一点,但没有全局更改功能?

3 个答案:

答案 0 :(得分:2)

您可以修补函数b,并将其替换为其他函数。在Python 3中使用unittest.mock,或在Python 2中使用mock

from unittest.mock import patch

def c():
    with patch('b', decorator(b)):
        a()

# Or, as a decorator
@patch('b', decorator(b))
def c():
    a()

通过修补,您基本上用自己的实例替换b实例。

答案 1 :(得分:1)

Python允许任何对象成为可调用的,而不仅仅是函数。

您可以使用以下内容:

class A(object):
    def __init__(self, func=b):
        self.func = func
    def __call__(self):
        # do stuff
        self.func()
        # do other stuff

然后使用a = A()a()只会调用f,但如果您编写c = A(decorator(b))c()将调用已修饰的版本

答案 2 :(得分:1)

由于您正在重新绑定b(),因此调用a()会尊重更新后的b(),您可以保存原始b(),然后将其恢复。这可能不是最有效的方式,但它对我有用。

import copy
def c():
    global b
    orig_b = copy.deepcopy(b)
    b = decorator(b)
    a()
    b = orig_b