【发布时间】:2021-04-24 20:02:51
【问题描述】:
我正在为 Python 打印函数编写包装器,但我的问题更笼统 - 包装了一个函数,解包它的正确方法是什么?
这可行,但我对此有两个担忧:
class Iprint():
def __init__(self, tab=4, level=0):
''' Indented printer class.
tab controls number of spaces per indentation level (equiv. to tabstops)
level is the indentation level (0=none)'''
global print
self.tab = tab
self.level = level
self.old_print = print
print = self.print
def print(self, *args, end="\n", **kwargs):
indent = self.tab * self.level
self.old_print(" "*indent, end="", **kwargs)
self.old_print(*args, end=end, **kwargs)
indent = Iprint()
indent.level = 3
print("this should be indented")
print = indent.old_print
print("this shouldn't be indented")
我的两个担忧:
-
如果有第二个
Iprint()类的实例化会发生什么?这看起来很尴尬,也许我应该阻止 - 但是如何? -
倒数第二行
print = indent.old_print“解开”打印函数,将其返回到原来的函数。这似乎也很尴尬 - 如果忘记了怎么办?
我可以在 __exit__ 方法中执行此操作,但这会将其使用限制为 with 块 - 我认为。有没有更好的办法?
Pythonic 的方法是什么?
(我还应该提到,我预计会有 嵌套 包装器,我认为这使得正确地做到这一点更加重要......)
【问题讨论】:
-
只有一个全局“print”,因此应该只有一个“old_print”。例如。您可以将其放置为类变量而不是实例变量。它可以具有默认值“无”,因此您可以测试是否已经存在活动替换。
-
我想说根本不要重新标记/重置 print() 函数。如果您想编辑它或自定义它并专门调用它,请不要理会它,只需编写您自己的。称它为
my_print()或其他任何名称。然后,您可以根据需要使用其中任何一个。也更清楚了。 -
@acrobat 这将破坏目的,即能够更改 print() 函数,以便可以调用预先存在的函数(打印) - 而无需更改其源代码。
-
@MichaelButscher 好的,我读到它建议我应该将其限制为单个替换并且不允许类的多个实例。您如何/何时建议调用解包器(析构函数,无论您想调用它)?使用 enter 和 exit 或其他方式?
-
我认为,如果您打算这样做,您对上下文管理器 (
with/__exit__) 的想法可能是最简洁的方法。