在python中是否有一种方法以编程方式确定控制台的宽度?我指的是一行中不换行的字符数,而不是窗口的像素宽度。

Edit

寻找在Linux上工作的解决方案


当前回答

下面是一个应该与Linux和Solaris兼容的版本。根据来自madchine的帖子和评论。需要子流程模块。

def termsize():
    import shlex, subprocess, re
    output = subprocess.check_output(shlex.split('/bin/stty -a'))
    m = re.search('rows\D+(?P\d+); columns\D+(?P\d+);', output)
    if m:
        return m.group('rows'), m.group('columns')
    raise OSError('Bad response: %s' % (output))
>>> termsize()
('40', '100')

其他回答

use

import console
(width, height) = console.getTerminalSize()

print "Your terminal's width is: %d" % width

编辑:哦,对不起。这不是python标准库,这里是console.py的源代码(我不知道它来自哪里)。

该模块的工作方式似乎是这样的:它检查termcap是否可用,如果是。它使用了那个;如果不支持,它会检查终端是否支持特殊的ioctl调用,如果不支持,它也会检查一些shell为此导出的环境变量。 这可能只适用于UNIX。

def getTerminalSize():
    import os
    env = os.environ
    def ioctl_GWINSZ(fd):
        try:
            import fcntl, termios, struct, os
            cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
        '1234'))
        except:
            return
        return cr
    cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
    if not cr:
        try:
            fd = os.open(os.ctermid(), os.O_RDONLY)
            cr = ioctl_GWINSZ(fd)
            os.close(fd)
        except:
            pass
    if not cr:
        cr = (env.get('LINES', 25), env.get('COLUMNS', 80))

        ### Use get(key[, default]) instead of a try/catch
        #try:
        #    cr = (env['LINES'], env['COLUMNS'])
        #except:
        #    cr = (25, 80)
    return int(cr[1]), int(cr[0])

试着“祝福”

我也在找同样的东西。它非常易于使用,并提供了在终端中着色、造型和定位的工具。你需要的很简单:

from blessings import Terminal

t = Terminal()

w = t.width
h = t.height

在Linux中工作就像一个魅力。(我不确定MacOSX和Windows)

在此下载及文件

或者你可以用pip安装它:

pip install blessings

我正在尝试从这里调用stty大小的解决方案:

columns = int(subprocess.check_output(['stty', 'size']).split()[1])

然而,这对我来说失败了,因为我正在编写一个脚本,期望在stdin上重定向输入,stty会抱怨“stdin不是终端”。

我能做到这样:

with open('/dev/tty') as tty:
    height, width = subprocess.check_output(['stty', 'size'], stdin=tty).split()

它是:

import os
columns, rows = os.get_terminal_size(0)
# or
import shutil
columns, rows = shutil.get_terminal_size()

shutil函数只是一个os的包装器,它可以捕捉一些错误并设置一个回退,但是它有一个巨大的警告-当管道爆裂!这是一个相当大的交易。 使用os.get_terminal_size(0)来代替管道时获取终端大小。

第一个参数0是一个参数,指示应该使用stdin文件描述符而不是默认的stdout。我们希望使用stdin,因为stdout在被管道传输时会分离自身,在这种情况下会引发错误。

我试图弄清楚什么时候使用stdout而不是stdin参数是有意义的,不知道为什么它是这里的默认值。

import os
rows, columns = os.popen('stty size', 'r').read().split()

使用“stty size”命令,根据python邮件列表中的线程,该命令在linux上相当通用。它打开“stty size”命令作为文件,从中“读取”,并使用一个简单的字符串分割来分隔坐标。

不像操作系统。environ["COLUMNS"]值(尽管使用bash作为我的标准shell,但我不能访问),数据也将是最新的,而我相信os。environ["COLUMNS"]值只在python解释器启动时有效(假设用户自那时起调整了窗口的大小)。

(参见@GringoSuave关于如何在python 3.3+上做到这一点的回答)