Using python decorator with or without parentheses

some_decorator in the first code snippet is a regular decorator:

@some_decorator
def some_method():
    pass

is equivalent to

some_method = some_decorator(some_method)

On the other hand, some_decorator in the second code snippet is a callable that returns a decorator:

@some_decorator()
def some_method():
    pass

is equivalent to

some_method = some_decorator()(some_method)

As pointed out by Duncan in comments, some decorators are designed to work both ways. Here’s a pretty basic implementation of such decorator:

def some_decorator(arg=None):
    def decorator(func):
        def wrapper(*a, **ka):
            return func(*a, **ka)
        return wrapper

    if callable(arg):
        return decorator(arg) # return 'wrapper'
    else:
        return decorator # ... or 'decorator'

pytest.fixture is a more complex example.

Leave a Comment