Skip to main content

Run Python code right in your Telegram messages

Project description

SimpleDeco

Decorators without nested functions

SimpleDeco is a way to create decorators with arguments and not to think about higher-order functions.

Instead, of nested functions, with SimpleDeco you split the decorator definitions into one or more plain functions.

Basic example

Let's create a count_time(iterations) decorator, which runs the given function the given number of iterations and counts the average time.

from time import time
from src.simpledeco import SimpleDeco, Wrapped


@SimpleDeco
def count_time(wrapped: Wrapped, iterations: int):
    t1 = time()

    for _ in range(iterations):
        # run the wrapped func with given arguments
        wrapped.func(*wrapped.args, **wrapped.kwargs)

    t2 = time()
    print('time:', (t2 - t1) / iterations)


@count_time(1000)
def f(x, y):
    return sum(range(x, y))


# Counts the sum of numbers from 1 to 50000 for 1000 times
# and prints the average time
f(1, 50000)

The similar code without SimpleDeco:

from time import time


def count_time(iterations: int):
    def decorator(func):
        def wrapper(*args, **kwargs):
            t1 = time()
            for _ in range(iterations):
                func(*args, **kwargs)
            t2 = time()
            print('time:', (t2 - t1) / iterations)

        return wrapper
    return decorator

@count_time(1000)
def f(x, y):
    return sum(range(x, y))


f(1, 50000)

Pretty more complex.

Wrapped object

SimpleDeco objects (like count_time above) are callable objects, which return decorators.

When using a SimpleDeco object with arguments as a decorator, the Wrapped instance and given arguments are passed.

Wrapped object has simple attributes:

  • wrapped.func - the given function
  • wrapped.args - a tuple of all positional arguments passed to a function
  • wrapped.kwargs - a dict of all keyword arguments passed to a function
  • wrapped.arguments - an object with all passed arguments

Thus, you can use wrapped.func(*wrapped.args, **wrapped.kwargs) to call the original function with original arguments.

If you need to use specific arguments, use wrapped.arguments attributes. For example, if you need to decorate only functions with x and y arguments:

@SimpleDeco
def count_time(wrapped: Wrapped, iterations: int):
    t1 = time()
    
    for _ in range(iterations):
        wrapped.func(wrapped.arguments.x, wrapped.arguments.y)
    
    t2 = time()
    print('x:', wrapped.arguments.x, 'y:', wrapped.arguments.y)
    print('time:', (t2 - t1) / iterations)

Hooks

Sometimes you need to do something after wrapping a function or before decorating it. There are special SimpleDeco methods for that.

  • simpledeco.after_wrapping decorates a function that takes wrapped SimpleDeco and wrapper as arguments
  • simpledeco.before_decorating decorates a function that takes wrapped SimpleDeco and decorator as arguments

For example:

from time import time
from src.simpledeco import SimpleDeco


@SimpleDeco
def count_time(wrapped, iterations):
    t1 = time()

    for _ in range(iterations):
        # run the wrapped func with given arguments
        wrapped.func(*wrapped.args, **wrapped.kwargs)

    t2 = time()
    print('time:', (t2 - t1) / iterations)


@count_time.after_wrapping
def after_wrapping(count_time_wrapped, wrapper):
    print('Running function for', count_time_wrapped.arguments.iterations, 'times')
    print('With arguments (1, 50000)')
    wrapper(1, 50000)


@count_time.before_decorating
def before_decorating(count_time_wrapped, decorator):
    print('Generated decorator with argument:', count_time_wrapped.arguments.iterations)
    # 'decorator' is the generated decorator


@count_time(1000)
def f(x, y):
    return sum(range(x, y))

The output:

Generated decorator with argument: 1000
Running function for 1000 times
With arguments (1, 50000)
time: 0.0022199389934539795

Compare with similar code without SimpleDeco:

from time import time


def count_time(iterations: int):
    def decorator(func):
        def wrapper(*args, **kwargs):
            t1 = time()
            for _ in range(iterations):
                func(*args, **kwargs)
            t2 = time()
            print('time:', (t2 - t1) / iterations)
        print('Running function for', iterations, 'times')
        print('With arguments (1, 50000)')
        wrapper(1, 50000)
        return wrapper
    print('Generated decorator with argument:', iterations)
    return decorator


@count_time(1000)
def f(x, y):
    return sum(range(x, y))

License

This project is licensed under the terms of the MIT license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

SimpleDeco-0.0.1.tar.gz (4.0 kB view details)

Uploaded Source

Built Distribution

SimpleDeco-0.0.1-py3-none-any.whl (4.4 kB view details)

Uploaded Python 3

File details

Details for the file SimpleDeco-0.0.1.tar.gz.

File metadata

  • Download URL: SimpleDeco-0.0.1.tar.gz
  • Upload date:
  • Size: 4.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.10.0

File hashes

Hashes for SimpleDeco-0.0.1.tar.gz
Algorithm Hash digest
SHA256 692adec79ebcc83e2541ca489ea53c8ca5a37a7efb078e0d84eaf5a5a9dd6af2
MD5 abfb3f4954dff381ff6e88274e5af3ce
BLAKE2b-256 68f7b3c3202a8d4257a3eb5a7903781876be09f0011647b273d2d1fe1e445a44

See more details on using hashes here.

File details

Details for the file SimpleDeco-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: SimpleDeco-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 4.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.10.0

File hashes

Hashes for SimpleDeco-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1636d0181c5d31e7de936bf34752cb8d35517aba38334db8780d13f77b52370e
MD5 92a439cbfd608891baf34c5247ea6b39
BLAKE2b-256 e288a9a3f2727925e5e7128a597eac7838e6e442d456ae961686758f76fdfe1e

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page