Skip to content

Easily create multi-purpose decorators that have access to the FQN of the original function.

License

Notifications You must be signed in to change notification settings

ricardosantosalves/py-fqn-decorators

 
 

Repository files navigation

FQN Decorators

https://secure.travis-ci.org/kpn-digital/py-fqn-decorators.svg?branch=master https://readthedocs.org/projects/fqn-decorators/badge/?version=latest

Installation

At the command line:

$ pip install fqn-decorators

Usage

.. py:currentmodule:: fqn_decorators.decorators

Introduction

By extending the :class:`~Decorator` class you can create simple decorators. Implement the :meth:`~Decorator.before` and/or :meth:`~Decorator.after` methods to perform actions before or after execution of the decorated item. The :meth:`~Decorator.before` method can access the arguments of the decorated item by changing the :attr:`~Decorator.args` and :attr:`~Decorator.kwargs` attributes. The :meth:`~Decorator.after` method can access or change the result using the :attr:`~Decorator.result` attribute. The :meth:`~Decorator.exception` method can be used for do something with an Exception that has been raised. In all three methods the :attr:`~Decorator.fqn` and :attr:`~Decorator.func` attributes are available.

Simple decorator

Create a simple decorator:

import fqn_decorators
import time

class time_it(fqn_decorators.Decorator):

    def before(self):
        self.start = time.time()

    def after(self):
        duration = time.time() - self.start
        print("{0} took {1} seconds".format(self.fqn, duration))


@time_it
def my_function():
    time.sleep(1)

>>>my_function()
__main__.my_function took 1.00293397903 seconds

Decorator with arguments

It is also very easy to create a decorator with arguments.

Note

It is not possible to create decorators with non-keyworded arguments. To create a decorator that supports non-keyworded arguments see the :ref:`Advanced Usage <usage_advanced_non_keyword_decorators>` section.

Example:

import fqn_decorators
import time

class threshold(fqn_decorators.Decorator):

    def before(self):
        self.start = time.time()

    def after(self):
        duration = time.time() - self.start
        treshold = self.params.get('threshold')
        if threshold and duration > threshold:
            raise Exception('Execution took longer than the threshold')


@threshold(threshold=2)
def my_function():
    time.sleep(3)

>>> my_function()
Exception: Execution took longer than the threshold

Async Decorator

There's also support for decorating coroutines (or any awaitable), for Python >=3.5 only.

The implementation is the same as with the sync version, just inherit from :class:`~fqn_decorators.async.AsyncDecorator` instead.

Example:

import asyncio
import time
from fqn_decorators.async import AsyncDecorator

class time_it_async(AsyncDecorator):

    def before(self):
        self.start = time.time()

    def after(self):
        duration = time.time() - self.start
        print("{0} took {1} seconds".format(self.fqn, duration))

@time_it_async
async def coro():
    await asyncio.sleep(1)

>>> loop = asyncio.get_event_loop()
>>> loop.run_until_complete(coro())
__main__.coro took 1.001493215560913 seconds

About

Easily create multi-purpose decorators that have access to the FQN of the original function.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Python 94.7%
  • Makefile 5.1%
  • Dockerfile 0.2%