首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类似于列的输出- python库

类似于列的输出- python库
EN

Stack Overflow用户
提问于 2009-09-08 23:12:30
回答 4查看 3.1K关注 0票数 2

Debian的apt工具输出结果是一致宽度列。例如,尝试运行“智能搜索svn”。所有名称都出现在宽度相同的第一列中。

现在,如果调整终端的大小,则相应地调整列的宽度。

是否有一个Python库可以让人做到这一点?请注意,库必须知道终端的宽度,并将表作为输入--例如,可以是[('rapidsvn', 'A GUI client for subversion'), ...]。您还可以为第一列(或任何列)指定最大宽度。还请注意,如果超过终端宽度,下面第二列中的字符串是如何被裁剪的。因此没有引入不想要的第二行。

代码语言:javascript
复制
$ aptitude search svn
[...]
p   python-svn-dbg                    - A(nother) Python interface to Subversion (d
v   python2.5-svn                     -                                            
v   python2.6-svn                     -                                            
p   rapidsvn                          - A GUI client for subversion                
p   statsvn                           - SVN repository statistics                  
p   svn-arch-mirror                   - one-way mirroring from Subversion to Arch r
p   svn-autoreleasedeb                - Automatically release/upload debian package
p   svn-buildpackage                  - helper programs to maintain Debian packages
p   svn-load                          - An enhanced import facility for Subversion 
p   svn-workbench                     - A Workbench for Subversion                 
p   svnmailer                         - extensible Subversion commit notification t
p   websvn                            - interface for subversion repositories writt
$

编辑:(作为对亚历克斯以下答案的回应).输出将类似于‘智能搜索’,因为1)只有最后一列(这是一行中字符串最长的列)将被裁剪,2通常只有2-4列,但最后一列("description")至少要占用终端宽度的一半。3)所有行都包含相同数量的列,4)所有条目仅为字符串

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-09-09 03:19:43

我不认为有一种通用的、跨平台的方法来“获取终端的宽度”-- --绝对不是--“查看列环境变量”(见我对这个问题的评论)。在Linux和Mac上(我期望所有现代Unix版本),

代码语言:javascript
复制
curses.wrapper(lambda _: curses.tigetnum('cols'))

返回列数;但我不知道恶语在Windows中是否支持这一点。

一旦您确实拥有(来自os.environ‘’COLUMNS‘,如果您坚持,或通过诅咒,或从甲骨文,或默认为80,或任何其他您喜欢的方式),其余的是相当可行的。这是一项精细的工作,有很多错误的机会,而且很容易受到很多你没有完全弄清楚的详细说明的影响,比如:哪一栏被剪掉以避免包装--它总是最后一列,还是.?为什么要在示例输出中显示3列,而根据您的问题,只有两列传入.?如果不是所有行都有相同的列数,那么应该发生什么呢?表中的所有条目必须是字符串吗?还有其他很多类似的秘密。

因此,对所有您不表达的规范进行某种程度的任意猜测,一种方法可能是这样的:

代码语言:javascript
复制
import sys

def colprint(totwidth, table):
  numcols = max(len(row) for row in table)
  # ensure all rows have >= numcols columns, maybe empty
  padded = [row+numcols*('',) for row in table]
  # compute col widths, including separating space (except for last one)
  widths = [ 1 + max(len(x) for x in column) for column in zip(*padded)]
  widths[-1] -= 1
  # drop or truncate columns from the right in order to fit
  while sum(widths) > totwidth:
    mustlose = sum(widths) - totwidth
    if widths[-1] <= mustlose:
      del widths[-1]
    else:
      widths[-1] -= mustlose
      break
  # and finally, the output phase!
  for row in padded:
    for w, i in zip(widths, row):
      sys.stdout.write('%*s' % (-w, i[:w]))
    sys.stdout.write('\n')
票数 2
EN

Stack Overflow用户

发布于 2009-09-18 21:45:44

更新colprint例程现在可以在苹果b 苹果b托管在GitHub中中使用。

以下是你们感兴趣的人的完整计划:

代码语言:javascript
复制
# This function was written by Alex Martelli
# http://stackoverflow.com/questions/1396820/
def colprint(table, totwidth=None):
    """Print the table in terminal taking care of wrapping/alignment

    - `table`:    A table of strings. Elements must not be `None`
    - `totwidth`: If None, console width is used
    """
    if not table: return
    if totwidth is None:
        totwidth = find_console_width()
        totwidth -= 1 # for not printing an extra empty line on windows
    numcols = max(len(row) for row in table)
    # ensure all rows have >= numcols columns, maybe empty
    padded = [row+numcols*('',) for row in table]
    # compute col widths, including separating space (except for last one)
    widths = [ 1 + max(len(x) for x in column) for column in zip(*padded)]
    widths[-1] -= 1
    # drop or truncate columns from the right in order to fit
    while sum(widths) > totwidth:
        mustlose = sum(widths) - totwidth
        if widths[-1] <= mustlose:
            del widths[-1]
        else:
            widths[-1] -= mustlose
            break
    # and finally, the output phase!
    for row in padded:
        print(''.join([u'%*s' % (-w, i[:w])
                       for w, i in zip(widths, row)]))

def find_console_width():
    if sys.platform.startswith('win'):
        return _find_windows_console_width()
    else:
        return _find_unix_console_width()
def _find_unix_console_width():
    """Return the width of the Unix terminal

    If `stdout` is not a real terminal, return the default value (80)
    """
    import termios, fcntl, struct, sys

    # fcntl.ioctl will fail if stdout is not a tty
    if not sys.stdout.isatty():
        return 80

    s = struct.pack("HHHH", 0, 0, 0, 0)
    fd_stdout = sys.stdout.fileno()
    size = fcntl.ioctl(fd_stdout, termios.TIOCGWINSZ, s)
    height, width = struct.unpack("HHHH", size)[:2]
    return width
def _find_windows_console_width():
    """Return the width of the Windows console

    If the width cannot be determined, return the default value (80)
    """
    # http://code.activestate.com/recipes/440694/
    from ctypes import windll, create_string_buffer
    STDIN, STDOUT, STDERR = -10, -11, -12

    h = windll.kernel32.GetStdHandle(STDERR)
    csbi = create_string_buffer(22)
    res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)

    if res:
        import struct
        (bufx, bufy, curx, cury, wattr,
         left, top, right, bottom,
         maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
        sizex = right - left + 1
        sizey = bottom - top + 1
    else:
        sizex, sizey = 80, 25

    return sizex
票数 4
EN

Stack Overflow用户

发布于 2009-09-09 01:17:06

好吧,智能使用cwidget来格式化仅文本显示中的列。您可以调用cwidget为它编写一个python扩展,但我认为这不值得.您可以使用自己喜欢的方法来获取图表中实际的水平大小,并计算自己。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1396820

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档