Как переопределить функцию печати с помощью оболочки при изменении стандартного вывода - PullRequest
1 голос
/ 17 марта 2020

Я пытаюсь создать оболочку, которая имеет следующие цели:

  1. Чтобы перехватить отпечатки для любой функции, чтобы сохранить их на потом (давайте вернем список на данный момент)
  2. Для переопределения распечаток также в обернутых функциях, чтобы добавить метку времени для лучшей регистрации и получения дополнительной информации (я не хочу log.info (), потому что это подразумевает изменение распечаток в обернутой функции, и если я хочу сделайте это в обёртке позже, я потеряю точность времени)

цель всегда состоит в том, чтобы ничего не менять в функции-обёртке, кроме как только обернуть их

Здесь мой код до сих пор:

def my_decorator(func):
    def wrapped_func(*args,**kwargs):
         return func("Here we add a timestamp",*args,**kwargs)
    return wrapped_func

def list_prints_to_logs(list_prints):
    for log in list_prints:
        logger.info(log)

def my_handler(func):
    def wrapper(*args,**kwargs):

        print('this is BEFORE the function')
        old_print = print                        
        print = my_decorator(print)

        ### catching the outputs of the function
        old_stdout = sys.stdout
        sys.stdout = tempstdout = StringIO()
        results = func(*args,**kwargs)  # THE ERROR STARTS IN HERE AFTER ENTERING THIS FUNCTION
        sys.stdout = old_stdout


        print('this is AFTER the function')
        prints_in_function = tempstdout.getvalue().splitlines()
        list_prints_to_logs(prints_in_function)  

        #trying to return the print like it was before
        print = old_print 
        print(*prints_in_function, sep='\n')        

        return results
    return wrapper


@my_handler
def my_func(arg=1,kwarg='yes'):

    print('this is inside the Function')
    print('this is second print in the function')


my_func()

и возвращаемая мне ошибка:

UnboundLocalError: local variable 'print' referenced before assignment

строка ошибки началась с печати внутри my_fun c

Я сталкиваюсь с трудностями в том, как временно переопределить функцию и сохранить это переопределение для следующих вызовов,

1 Ответ

2 голосов
/ 17 марта 2020

UnboundLocalError вызывается, когда вы присвоили локальную переменную, но использовали ее перед назначением.
Обычно, когда вы используете оператор присваивания в функции, она связывает локальную переменную.
Если вы хотите чтобы связать переменную gloabl, вы должны использовать оператор global перед заданием.

def my_handler(func):
    def wrapper(*args,**kwargs):
        global print
        ...
        print = my_decorator(print)
        ...
        print = old_print 
        print(*prints_in_function, sep='\n')        

        return results
    return wrapper

Однако этот декоратор не влияет на внешний модуль. Если вы хотите повлиять на включение других модулей, вам нужно перепривязать builtins.print.

import builtins
def my_handle(func):
    def wrapper(*args,**kwargs):
        ...
        builtins.print = my_decorator(print)
        ...
        builtins.print = old_print
        ...
    return wrapper
...