在调用i之前检测方法是否被修饰

2024-09-30 01:28:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我编写了一个Python流控制框架,其工作原理与unittest.TestCase非常相似:用户创建一个从框架类派生的类,然后编写自定义的task_*(self)方法。框架发现并运行它们:

###################
# FRAMEWORK LIBRARY
###################
import functools

class SkipTask(BaseException):
    pass

def skip_if(condition):
    def decorator(task):
        @functools.wraps(task)
        def wrapper(self, *args, **kargs):
            if condition(self):
                raise SkipTask()
            return task(self, *args, **kargs)
        return wrapper
    return decorator

class MyFramework(object):
    def run(self):
        print "Starting task"
        try:
            self.task()
        except SkipTask:
            print "Skipped task"
        except Exception:
            print "Failed task"
            raise
        else:
            print "Finished task"

#############
# USER SCRIPT
#############
class MyUserClass(MyFramework):
    skip_flag = True

    @skip_if(lambda self: self.skip_flag)
    def task(self):
        print "Doing something"

if __name__ == '__main__':
    MyUserClass().run()

输出:

^{pr2}$

我想更改框架,这样每当@skip_if的条件是True,包装器就不会打印"Starting task"。 我试过了,但没用:

def skip_if(condition):
    def decorator(task):
        print "decorating "  + str(task)
        task.__skip_condition = condition
        return task
    return decorator

class MyFramework(object):
    def run(self):
        try:
            if self.task.__skip_condition():
                print "Skipped task"
                return
        except AttributeError:
            print str(self.task) + " is not decorated"
            pass

        print "Starting task"
        try:
            self.task()
        except Exception as e:
            print "Failed task: " + str(e)
            raise
        else:
            print "Finished task"

输出:

decorating <function task at 0x194fcd70>
<bound method MyUserClass.task of <__main__.MyUserClass object at 0x195010d0>> is not decorated
Starting task
Doing something
Finished task

为什么没有跳过任务呢?在


Tags: self框架taskreturnifdefdecoratorcondition
1条回答
网友
1楼 · 发布于 2024-09-30 01:28:39

您使用的是一个双下划线名称,它在run方法中经历了private name mangling。在

单步执行调试器时,我得到:

AttributeError: "'function' object has no attribute '_MyFramework__skip_condition

不要在这里使用双下划线名称;如果将函数属性重命名为_skip_condition,则代码正常工作(前提是您绑定了条件函数或显式地传入self):

^{pr2}$

随着这些变化,输出变成:

decorating <function task at 0x1071a1b90>
Skipped task

相关问题 更多 >

    热门问题