开发者

Specify action to be performed at the end of many functions

I have a python object in which a bunch of functions need to perform the same action at the end of execution, just before the return statement. For example:

def MyClass(object):
    def __init__(self):
        pass

    def update_everything(self):
        '''update everything'''
        pass

    def f1(self):
   开发者_高级运维     #do stuff
        self.update_everything()
        return result

    def f2(self):
        #do stuff
        self.update_everything()
        return result

    def f3(self):
        #do stuff
        self.update_everything()
        return result

What is the best (pythonic?) way to do this, except for the explicit calls at the end of each function?


I think that any solution to your problem would be unpythonic, because (as Tim Peters says in the Zen of Python (import this)):

Explicit is better than implicit.


Yes, using a decorator is actually more code, but it does have the advantage that you can see that a method updates everything at a glance. It's a different kind of explicitness ;-)

def update_after(m):
    """ calls self.update_everything() after method m """
    def decorated(self, *args, **kwargs):
        r = m(self, *args, **kwargs)
        self.update_everything()
        return r
    return decorated


def MyClass(object):
    def __init__(self):
        pass

    def update_everything(self):
        '''update everything'''
        pass

    @update_after
    def f1(self):
        #do stuff
        return result

    @update_after
    def f2(self):
        #do stuff
        return result

    @update_after
    def f3(self):
        #do stuff
        return result


Maybe the other way round?

class MyClass(object):
    def update(self, func):
        value = func()
        # do something common
        return value

    def f1(self):
        # do stuff
        return result

    def f2(self):
        # do stuff
        return result

my_object = MyClass()

my_object.update(my_object.f1)

Edit: You could also write it in such way that update accepts a string being a name of the object's method. This would prevent running other objects' methods.

my_object.update('f1')
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜