python - 我的装饰器适用于常规功能,但不适用于实例

标签 python python-2.7 decorator

我有一个工作装饰器,可以在一段时间内运行一个方法 True 并且它在常规函数上运行良好。当我尝试装饰实例的函数时出现问题。

这是装饰器:

from threading import Thread


def run_in_while_true(f):
    def decorator(break_condition=False):
        def wrapper(*args, **kwargs):
            while True:
                if break_condition:
                    return
                f(*args, **kwargs)
         return wrapper
    return decorator


class A(object):
    @run_in_while_true
    def print_ch(self, ch):
         print ch

@run_in_while_true
def print_with_dec(ch):
     print ch


print_with_dec()('f')  # Call 1
# If i would want to pass a break condition i would write this
print_with_dec(1==1 and 2*2==4)('f')

a = A()
a.print_ch()('4')  # Call 2

`

调用 1 按预期运行并打印大量 f。 由于某种原因,调用 2 获取了 self 参数,其中break_condition 是,并且因为检查break_condition 为true 并且函数返回。

我需要以什么方式更 retrofit 饰器才能使其也适用于对象?提前致谢

最佳答案

你生成的代码看起来真的很奇怪:

a.print_ch()('4')  # Call 2

这是因为你的装饰器中有一个额外的层:

def run_in_while_true(f):
    def decorator(break_condition=False):
        def wrapper(*args, **kwargs):

@run_in_while_true 装饰器将返回 decorator,必须调用它才能返回 wrapper,必须调用它来评估一个结果。 @run_in_while_true 作为装饰的一部分被自动调用。另外两个需要两组括号,如代码中所示。

这是一个问题,因为方法调用(例如 a.print_ch())会自动将调用者传递给第一次调用:

a.print_ch()('4')
# is much the same as
# A.print_ch(self=a)('4')

这解释了为什么您的调用者会处于 break_condition 状态。

我建议你尝试统一两个内部函数。只需将诸如 break_conditionbreak_whenbreak_if 之类的命名参数传递给函数/方法,并让包装器拦截该值: 导入函数工具

def run_until_done(func):
    @functools.wraps
    def wrapper(*args, break_if=None, **kwargs):
        done = break_if if callable(break_if) else lambda: break_if

        while not done():
            func(*args, **kwargs)
     return wrapper

@run_until_done
def print_with_dec(ch):
    print ch

print_with_dec('4', break_if=lambda: 1==1 and is_done())

关于python - 我的装饰器适用于常规功能,但不适用于实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54587513/

相关文章:

python - 在Python中现有的内置类方法中添加装饰器

Python - 对嵌套列表的列表进行排序

Python 在运行测试时导入 src 模块

python - 如何将 numpy 掩码数组保存到文件

python - 你如何在 Python 中继承 Queue

使用pip后Python 2.7突然消失了

python - 装饰器中丢失的回溯信息

python - Pandas:对于 2 个或多个特定列值完全相同的行组,如何将唯一整数分配为新列

excel - 如何在 pytest excel 报告中添加测试步骤中的值

java - 如何在 RecyclerView 中设置负边距装饰?或者为什么这是不可能的?