Using the same decorator (with arguments) with functions and methods

后端 未结 5 1523
隐瞒了意图╮
隐瞒了意图╮ 2020-12-05 00:54

I have been trying to create a decorator that can be used with both functions and methods in python. This on it\'s own is not that hard, but when creating a decorator that

5条回答
  •  死守一世寂寞
    2020-12-05 01:47

    A partial (specific) solution I have come up with relies on exception handling. I am attempting to create a decorator to only allow certain HttpRequest methods, but make it work with both functions that are views, and methods that are views.

    So, this class will do what I want:

    class methods(object):
        def __init__(self, *_methods):
            self.methods = _methods
    
        def __call__(self, func): 
            @wraps(func)
            def inner(*args, **kwargs):
                try:
                    if args[0].method in self.methods:
                        return func(*args, **kwargs)
                except AttributeError:
                    if args[1].method in self.methods:
                        return func(*args, **kwargs)
                return HttpResponseMethodNotAllowed(self.methods)
            return inner
    

    Here are the two use cases: decorating a function:

    @methods("GET")
    def view_func(request, *args, **kwargs):
        pass
    

    and decorating methods of a class:

    class ViewContainer(object):
        # ...
    
        @methods("GET", "PUT")
        def object(self, request, pk, *args, **kwargs):
            # stuff that needs a reference to self...
            pass
    

    Is there a better solution than to use exception handling?

提交回复
热议问题