[英]How can I make Python 3's Print fit the size of the command prompt?
Python 3 can easily handle printing a lot of text: Python 3可以轻松处理打印大量文本:
text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vitae odio quis felis consectetur blandit. Etiam mattis vehicula ex id sodales. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris fermentum semper nisi vel aliquam. Ut nec facilisis lectus. Maecenas auctor blandit condimentum. Donec finibus orci ac imperdiet congue. Pellentesque sem leo, commodo non metus ac, posuere maximus lorem. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. "
print(text)
The problem is that this text is printed like this: 问题是这个文本打印如下:
This is of course not very good for readability of the text. 这对于文本的可读性当然不是很好。 Going through all of the text by hand to insert white lines makes for quite a hassle. 手动浏览所有文本以插入白线会让人非常麻烦。 I have seen this question , but I'm wondering if there's an option to do this automatically. 我已经看到了这个问题 ,但我想知道是否有一个选项可以自动执行此操作。
As mentioned in the comments, pprint
and textwrap
can be used to align output to a given width. 正如评论中所提到的, pprint
和textwrap
可用于将输出对齐到给定的宽度。 Given that, the only trick is determining the width to use. 鉴于此,唯一的技巧是确定要使用的宽度。 You could just use 78 or 80 and assume the window is that large, but that means bad wrapping if the terminal is smaller, and wasted space if it's larger. 您可以使用78或80并假设窗口很大,但这意味着如果终端较小则包装不良,如果较大则浪费空间。
To check the actual width for use with pprint
/ textwrap
, if you're on Python 3.3 or higher, you can use shutil.get_terminal_size
: 要检查用于pprint
/ textwrap
的实际宽度,如果您使用的是Python 3.3或更高版本,则可以使用shutil.get_terminal_size
:
import shutil
def get_terminal_columns():
return shutil.get_terminal_size().columns
If you can't use 3.3+, you can use the curses
module to determine the size in a somewhat more complicated way: 如果你不能使用3.3+,你可以使用curses
模块以更复杂的方式确定大小:
import curses
def get_terminal_columns():
try:
# Initialize curses for terminal and check dimensions
rows, cols = curses.initscr().getmaxyx()
finally:
# Unload curses to release control of terminal so it behaves normally
curses.endwin()
return cols
Using one of these functions, you can then define: 使用这些功能之一,您可以定义:
from __future__ import print_function # Only needed on Py2
import textwrap
def print_autobreak(*args, sep=' '):
width = get_terminal_columns() # Check size once to avoid rechecks per "paragraph"
# Convert all args to strings, join with separator, then split on any newlines,
# preserving line endings, so each "paragraph" wrapped separately
for line in sep.join(map(str, args)).splitlines(True):
# Py3's print function makes it easy to print textwrap.wrap's result as one-liner
print(*textwrap.wrap(line, width), sep="\n")
This automatically performs line breaking between words based on the terminal size, preserves existing "hard" newlines and spaces, and (partially) matches the behavior of print
by allowing multiple arguments with an optional separator. 这会根据终端大小自动执行单词之间的换行,保留现有的“硬”换行符和空格,并通过允许带有可选分隔符的多个参数(部分)匹配print
行为。 It needs to completely realize the output string before printing (the original print
can print one-by-one, reducing memory usage a bit for huge outputs), but that's a side-effect of performing appropriate global wrapping. 它需要在打印之前完全实现输出字符串(原始print
可以逐个打印,减少大量输出的内存使用量),但这是执行适当的全局包装的副作用。
If you need more complete line breaking handling (so two prints can occur without newlines, yet the second one accounts for the length of the first), you'll need a more stateful printer (to remember used characters on a line) or invent something a tad more complex with full curses
functionality. 如果你需要更完整的换行处理(所以两个打印可以没有换行,但第二个占第一个的长度),你需要一个更有状态的打印机(记住一行中使用的字符)或发明一些东西一个更复杂的完整curses
功能。 I'll leave that as an exercise. 我会把它留作练习。
You might have a look at this Gist . 你可能会看看这个要点 。
Then using the returned values to split the string in subsequent print
calls accordingly. 然后使用返回的值相应地在后续print
调用中拆分字符串。
IDLE shell : IDLE shell :
Width can be retrieved with sys.stdout.shell.width and that will raise an AttributeError on any other environment (in which case you would use the gist) 可以使用sys.stdout.shell.width检索宽度,这将在任何其他环境中引发AttributeError(在这种情况下,您将使用gist)
The hard part will be to get the size of the console (Windows world) or terminal (Unix), because I know no portable way to get it. 困难的部分是获得控制台(Windows世界)或终端(Unix)的大小,因为我知道没有可移植的方式来获得它。 It involves (as shown in the Gist proposed by @MaximeB): 它涉及(如@MaximeB提出的要点所示):
GetConsoleScreenBufferInfo
from windows API for Windows (via ctypes.windll
使用GetConsoleScreenBufferInfo
从Windows API的Windows(通过ctypes.windll
fcntl.ioctl
on Linux or other Unixes 在Linux或其他Unix上使用fcntl.ioctl
not speaking of possible corner cases... But the Gist could be enough for your requirements if you only use Windows. 没有谈到可能的角落案例...但如果你只使用Windows,那么Gist可能足以满足你的要求。
Once you have found the width, of if you can accept a static width of 72 or 80 or any other value, the texwrap module can do the trick: 一旦找到宽度,如果你可以接受72或80的静态宽度或任何其他值,texwrap模块可以做到这一点:
for i in textwrap.wrap(text, 72):
print i
gives: 得到:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vitae
odio quis felis consectetur blandit. Etiam mattis vehicula ex id
sodales. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris
fermentum semper nisi vel aliquam. Ut nec facilisis lectus. Maecenas
auctor blandit condimentum. Donec finibus orci ac imperdiet congue.
Pellentesque sem leo, commodo non metus ac, posuere maximus lorem. Class
aptent taciti sociosqu ad litora torquent per conubia nostra, per
inceptos himenaeos.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.