LINUX.ORG.RU

python как вставить переменную в декоратор

 ,


0

1

Привет, есть вот такой шаблон

def log_in_out(func):

    def decorated_func(*args, **kwargs):
        print("Enter ", func.__name__)
        result = func(*args, **kwargs)
        print("Leave ", func.__name__)
        return result

    return decorated_func

@log_in_out
def my_function():
    print("Inside my_function")
    return 42


val = my_function()

print(val)

Который выдает соответственно

Enter  my_function
Inside my_function
Leave  my_function

я бы хотел, чтобы вместо текста Enter my_function и Leave my_function он показывал переменные, да еще и в одну строчку, но первую перед выполнением функции, а вторую после. Я не знаю как и туда их засунуть.

те я вызываю функцию и передаю или декоратору переменную message , а декоратор делает вот так:

message="Start something" 
вызвали функцию с декоратором

print(message,'.'*(60-len(message)), end = '')
тут  выполняем код функции  и она отдает еще код ошибки p.returncode
print('Error') if p.returncode else print('Done')

в результате я хочу иметь такой вывод:

Start something........ Done
или 
Start something........ Error

Простите, что там сумбурно.

★★★★
Ответ на: комментарий от tz4678

спасибо, вот получилось что:

#!/usr/bin/env python3

from functools import wraps

def mydecorator_not_actually(message):
    def true_decorator(f):
        @wraps(f)
        def wrapped(*args, **kwargs):
            print(message,'.'*(60-len(message)), end = '')
            r = f(*args, **kwargs)
            print("Done")
            return r
        return wrapped
    return true_decorator

@mydecorator_not_actually(message="Start something")
def myfunc(myarg):
    return "return value"

r = myfunc('test')
print(r)

$ ./test.py 
Start something .............................................Done
return value


сейчвс буду это натравливать на боевую функцию с кодами ошибок

constin ★★★★
() автор топика
Ответ на: комментарий от constin

Как-то так

import functools
import logging
import sys
from inspect import signature, Parameter

logger = logging.getLogger(__name__)
logging.basicConfig(stream=sys.stdout, level=logging.INFO)


def inspect_function(func):
    sig = signature(func)
    param_names = []
    param_defaults = {}
    for param_name, param in sig.parameters.items():
        param_names.append(param_name)
        if param.default is Parameter.empty:
            continue
        param_defaults[param_name] = param.default
    return tuple(param_names), tuple(param_defaults.items())


def log_in_out(func):
    param_names, param_defaults = inspect_function(func)

    @functools.wraps(func)
    def inner(*args, **kwargs):
        all_params = dict(param_defaults)
        all_params.update(zip(param_names, args))
        all_params.update(kwargs)
        logger.info('%s called with: %s', func.__name__, ', '.join(f'{x}={y}' for x, y in all_params.items()))

        r = func(*args, **kwargs)
        logger.info('result=%s', r)

    return inner


@log_in_out
def doit(a, b, c=3):
    return c * (a + b)


doit(1, 2)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.