3

假设我有一个函数或方法在执行它所做的每个操作之前执行重复的操作,例如检查值,如下所示:

def myfunc():
    if mybool:
        do_operation_1()
    else:
        return

    if mybool:
        do_operation_2()
    else:
        return

    ...

这些检查会重复进行,最终会浪费大量时间和键盘弹簧,尤其是在经常需要它们的时候。

如果您可以控制操作功能,例如,do_operation_N您可以使用检查布尔值的东西来装饰功能。

但是,如果您无法控制各个do_operation_N操作怎么办?如果,对于函数或方法中的每一行,我希望执行相同的检查,是否有某种方法可以“插入”它而不在每个操作行上明确写入?例如,是否有一些装饰魔法可以让我执行以下操作?

def magic_decorator(to_decorate):
    def check(*args, **kwargs):
        for call in to_decorate: #magic
            if mybool:
                to_decorate.do_call(call) #magic
            else:
                return #or break, raise an exception, etc
    return check

@magic_decorator
def myfunc():
    do_operation_1()
    do_operation_2()
    ...

如果有办法实现这一点,我不在乎它是否使用装饰器;我只想用某种方式说“对于函数/方法 X 中的每一行,先做 Y”。

上面一个方法的“神奇”示例do_call是我所追求的简写,但它会遇到个别行的乱序执行的严重问题(例如,如果函数的第一行是变量赋值,它的其次是使用该变量,无序执行它们会导致问题)。

需要明确的是:外部控制函数执行的逐行顺序的能力不是我想要实现的:理想情况下,我只是实现一些以自然执行顺序执行操作的东西每次myfunc都做某事。如果“做某事”最终仅限于“调用函数或方法”(不包括赋值、if检查等),那很好。

4

2 回答 2

6

按顺序存储您的操作,然后使用循环:

ops = (do_operation_1, do_operation_2, do_operation_3)

for op in ops:
    if mybool:
        op()
    else:
        return
于 2012-11-02T16:00:28.443 回答
0

本质上,您可以从修饰函数中提取文件和行号,重新读取函数,将其编译为 AST,在 AST 中插入节点,然后编译 AST 并将其用作函数。

此方法可用于非常长的函数,如果您使用上述方法,这是一个问题。

于 2015-08-25T00:28:59.453 回答