【发布时间】:2018-02-08 18:51:41
【问题描述】:
编辑:我第一次尝试问这个问题可能有点不专注/措辞不佳,这是对我正在尝试做的事情的更好解释:
我正在尝试修改 python 运行的整个环境的打印函数的默认行为,而不必修改正在运行的每个文件。
我正在尝试装饰打印功能(我知道有很多方法可以做到这一点,例如覆盖它,但这不是我要问的问题)所以我可以让它打印出一些调试信息并强制它总是冲洗。我是这样做的:
def modify_print(func):
# I made this so that output always gets flushed as it won't by default
# within the environment I'm using, I also wanted it to print out some
# debugging information, doesn't really matter much in the context of this
# question
def modified_print(*args,**kwargs):
return func(f"some debug prefix: ",flush=True,*args,**kwargs)
return modified_print
print = modify_print(print)
print("Hello world") # Prints "some debug prefix Hello World"
但是,我正在尝试在整个应用程序中修改此行为。我知道我可以手动装饰/覆盖/导入每个文件中的打印功能,但是我想知道是否有某种方法可以全局配置我的 python 环境以在任何地方装饰这个功能。我能想到的唯一方法是编辑 python 源代码并构建修改后的版本。
编辑: 这是我想要实现的行为,感谢 Match 的帮助。 它会在您在 python 环境中调用打印函数的任何地方打印出行号和文件名。这意味着您不必在所有文件中手动导入或覆盖任何内容。
https://gist.github.com/MichaelScript/444cbe5b74dce2c01a151d60b714ac3a
import site
import os
import pathlib
# Big thanks to Match on StackOverflow for helping me with this
# see https://stackoverflow.com/a/48713998/5614280
# This is some cool hackery to overwrite the default functionality of
# the builtin print function within your entire python environment
# to display the file name and the line number as well as always flush
# the output. It works by creating a custom user script and placing it
# within the user's sitepackages file and then overwriting the builtin.
# You can disable this behavior by running python with the '-s' flag.
# We could probably swap this out by reading the text from a python file
# which would make it easier to maintain larger modifications to builtins
# or a set of files to make this more portable or to modify the behavior
# of more builtins for debugging purposes.
customize_script = """
from inspect import getframeinfo,stack
def debug_printer(func):
# I made this so that output always gets flushed as it won't by default
# within the environment I'm running it in. Also it will print the
# file name and line number of where the print occurs
def debug_print(*args,**kwargs):
frame = getframeinfo(stack()[1][0])
return func(f"{frame.filename} : {frame.lineno} ", flush=True,*args,**kwargs)
return debug_print
__builtins__['print'] = debug_printer(print)
"""
# Creating the user site dir if it doesn't already exist and writing our
# custom behavior modifications
pathlib.Path(site.USER_SITE).mkdir(parents=True, exist_ok=True)
custom_file = os.path.join(site.USER_SITE,"usercustomize.py")
with open(custom_file,'w+') as f:
f.write(customize_script)
【问题讨论】:
-
只需使用上面的代码作为包装器 - 即在重新定义
print之后,然后转到import并运行您的real应用程序。 -
是的,但是打印功能不会在每个文件中被覆盖,除非在每个单独的文件中手动导入或覆盖它。换句话说:修改python运行的整个环境的print函数的默认行为。
标签: python python-3.x