【问题标题】:Limiting print output限制打印输出
【发布时间】:2015-03-29 05:20:42
【问题描述】:

我有一些对象需要打印到终端(用于调试)。普通的print 函数几乎是完美的,只是有些对象太大了,所以print 会产生数百万行的输出。我想创建一个函数来做print 所做的事情,除了输出在预定义数量的字符后被截断,其余的替换为...

有什么好的方法吗?

请注意,性能是一个问题,所以理想情况下,我不希望保存一个千兆字节大小的字符串,然后从中取出前几个字符;同样,pprint 也有点问题,因为它对字典中的键进行排序(并且有数百万个键需要一段时间)。

例子:

obj = [ [1, 2, 3], list(range(1000000)) ]
my_print(obj, 20)
# should output:
# [[1, 2, 3], [0, 1, 2...

Python 3,如果重要的话。

【问题讨论】:

  • 如果您有嵌套的字典,可能pprint.pprint 和参数depth 设置会有所帮助?
  • @myaut 这不是我想要的,但它真的很有帮助!谢谢!
  • 你可以用reprlib定义你自己的表示。
  • @m0nhawk 我想就是这样。你能把它从评论移到答案吗?

标签: python python-3.x


【解决方案1】:

@m0nhawk 建议的 reprlib 模块(仅限 Python 3.x)正是为此目的而制作的。以下是您将如何使用它:

如果您对默认限制感到满意,您可以简单地使用reprlib.repr(obj)

import reprlib

obj = [[1, 2, 3], list(range(10000))]

print(reprlib.repr(obj))

输出:

[[1, 2, 3], [0, 1, 2, 3, 4, 5, ...]]

为了自定义available limits,只需创建一个reprlib.Repr 实例并设置适当的实例属性:

r = reprlib.Repr()
r.maxlist = 4       # max elements displayed for lists
r.maxstring = 10    # max characters displayed for strings

obj = [[1, 2, 3], list(range(10000)), 'looooooong string', 'a', 'b', 'c']

print(r.repr(obj))

输出:

[[1, 2, 3], [0, 1, 2, 3, ...], 'lo...ing', 'a', ...]

如果您正在处理序列引用自身的对象,您可以使用Repr.maxlevel 来限制递归深度:

lst = [1, 2, 3]
lst.append(lst)  # oh my!

r = reprlib.Repr()
r.maxlevel = 5   # max recursion depth

print(r.repr(lst))

输出:

[1, 2, 3, [1, 2, 3, [1, 2, 3, [1, 2, 3, [1, 2, 3, [...]]]]]]

注意reprlib.repr()返回一个字符串,但print不返回它(除非你在一个交互式控制台中,你输入的每个表达式的结果都会被计算并显​​示它的表示)。

【讨论】:

    【解决方案2】:

    为什么不在print 函数上做一个简单的切片包装器?

    def my_print(obj, depth):
        print(str(obj)[:depth])
    

    print 在写入输出流之前与str 执行相同的操作。因此,您要做的就是在将其传递到打印之前尽早进行该转换,然后切掉一块具有您想要的最大尺寸的部分。

    Python 切片是优雅的,因此像 'xyz'[:30000] 这样的字符串切片仅计算为 'xyz' 而不会引发错误。

    【讨论】:

    • 这会完美运行,只是它仍然需要很长时间才能运行。我有数十万个键的字典,其值是包含数百个项目的列表。将它们转换为 str 需要很长时间,所以理想情况下我想避免这种情况。
    • @max 我认为对str 的调用几乎是不可避免的。您可以尝试通过查看 Python 的特殊方法系统和 __str__ 来更改 str 所做的事情:docs.python.org/3/reference/datamodel.html#object.__str__ 但是,一个大问题是您无法更改像 dict 这样的内置类型的属性。我认为您可能会坚持在 dict 上实现自己的包装类,然后用您自己的自定义函数覆盖其 __str__ 函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    • 2015-12-30
    • 2020-11-03
    • 1970-01-01
    相关资源
    最近更新 更多