【问题标题】:Modify function's code in wrapper function修改包装函数中的函数代码
【发布时间】:2019-10-28 02:33:20
【问题描述】:

是否可以用包装它的函数替换函数的实际代码?这里我试图用log 语句替换print 语句:

import logging
import re

def print_to_log(func):
    def wrapper_print_to_log(*args, **kwargs):
        # how to do something like this?
        re.sub(r'print\s*\(',  'logging.info(', **function_code**)
        return func(*args, **wargs)
    return wrapper_print_to_log


@print_to_log
def greet(name='bob'):
    print ("Hello, %s" % name)
    print ("How are you sir?")

是否可以替换代码或做类似上述的事情?

【问题讨论】:

  • 您的目标是在日志记录方面具有灵活性,还是您真的对动态重写代码感兴趣,这里的代码只是一个示例?
  • @bjudson 实际上是为了重写代码——日志记录只是一个例子。
  • 你探索过猴子补丁(例如unittest.mock 模块)吗?

标签: python python-3.x decorator


【解决方案1】:

也许你可以临时替换 sys.stdout?

import logging
import re
import sys
import io

def print_to_log(func):
    def wrapper_print_to_log(*args, **kwargs):
        stdout = sys.stdout
        b = io.StringIO()
        sys.stdout = b
        try:
            return func(*args, **kwargs)
        finally:
            sys.stdout = stdout
            print(b.getvalue().upper())

    return wrapper_print_to_log

@print_to_log
def greet(name='bob'):
    print("Hello, %s" % name)
    print("How are you sir?")

greet('justin')

【讨论】:

  • 显然,在 python 3 上,您还可以将内置的 print 函数替换为任何其他函数:print = logging.info。之后只需使用 finally 块将print 恢复为内置函数即可。
  • 奇怪...替换打印似乎只能在交互式提示下工作。
  • 啊...但是可以在import builtins 之后分配给builtins.print。但现在我很好奇 OP 想要的是否真的可行。
猜你喜欢
  • 2023-04-10
  • 2018-12-11
  • 1970-01-01
  • 1970-01-01
  • 2015-09-13
  • 1970-01-01
  • 2014-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多