Question

Est-il possible en python pour déterminer la largeur de programmation de la console? Je veux dire le nombre de caractères qui correspond à une ligne sans emballage, et non la largeur en pixels de la fenêtre.

Modifier

Vous cherchez une solution qui fonctionne sur Linux

Était-ce utile?

La solution

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

utilise la commande « de taille de stty » qui, selon un fil sur la liste de diffusion python est raisonnablement universel sur linux. Il ouvre la commande « taille stty » comme un fichier, « lit » de celui-ci, et utilise une simple chaîne divisée pour séparer les coordonnées.

Contrairement aux os.environ [ « COLONNES »] valeur (que je ne peux pas accéder malgré l'utilisation bash comme mon shell standard) les données seront également alors je crois mise à jour du os.environ [ » COLONNES "] valeur ne serait valable que pour le moment du lancement de l'interpréteur python (supposons que l'utilisateur redimensionné la fenêtre depuis).

Autres conseils

Je ne sais pas pourquoi il est dans le module shutil, mais il y débarqua en Python 3.3, Interrogation de la taille de la borne de sortie :

>>> import shutil
>>> shutil.get_terminal_size((80, 20))  # pass fallback
os.terminal_size(columns=87, lines=23)  # returns a named-tuple

Une mise en œuvre à bas niveau est dans le module os.

A backport est maintenant disponible pour Python 3.2 et ci-dessous:

utilisation

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

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

EDIT : oh, je suis désolé. Ce n'est pas un python norme lib, voici la source de console.py (je ne sais pas où il est de).

Le module semble fonctionner comme ça: Il vérifie si termcap est disponible, quand oui. Il utilise que; si aucune vérifie si le terminal prend en charge un appel spécial ioctl et qui ne fonctionne pas, aussi, il vérifie les variables d'environnement des coquilles exportent pour cela. Cela fonctionnera probablement sous 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])

code ci-dessus n'a pas revenir résultat correct sur mon linux parce que winsize-struct dispose de 4 courts métrages non signés, non 2 courts métrages signés:

def terminal_size():
    import fcntl, termios, struct
    h, w, hp, wp = struct.unpack('HHHH',
        fcntl.ioctl(0, termios.TIOCGWINSZ,
        struct.pack('HHHH', 0, 0, 0, 0)))
    return w, h

et HP doivent contenir la largeur de pixel et la hauteur, mais ne sont pas.

J'ai cherché et trouvé une solution pour les fenêtres à:

http://code.activestate.com/recipes/ 440694-déterminer la taille de la fenêtre, sur--console windows /

et une solution pour Linux ici.

Voici donc une version qui fonctionne aussi bien sur Linux, OS X et Windows / Cygwin:

""" getTerminalSize()
 - get width and height of console
 - works on linux,os x,windows,cygwin(windows)
"""

__all__=['getTerminalSize']


def getTerminalSize():
   import platform
   current_os = platform.system()
   tuple_xy=None
   if current_os == 'Windows':
       tuple_xy = _getTerminalSize_windows()
       if tuple_xy is None:
          tuple_xy = _getTerminalSize_tput()
          # needed for window's python in cygwin's xterm!
   if current_os == 'Linux' or current_os == 'Darwin' or  current_os.startswith('CYGWIN'):
       tuple_xy = _getTerminalSize_linux()
   if tuple_xy is None:
       print "default"
       tuple_xy = (80, 25)      # default value
   return tuple_xy

def _getTerminalSize_windows():
    res=None
    try:
        from ctypes import windll, create_string_buffer

        # stdin handle is -10
        # stdout handle is -11
        # stderr handle is -12

        h = windll.kernel32.GetStdHandle(-12)
        csbi = create_string_buffer(22)
        res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
    except:
        return None
    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
        return sizex, sizey
    else:
        return None

def _getTerminalSize_tput():
    # get terminal width
    # src: http://stackoverflow.com/questions/263890/how-do-i-find-the-width-height-of-a-terminal-window
    try:
       import subprocess
       proc=subprocess.Popen(["tput", "cols"],stdin=subprocess.PIPE,stdout=subprocess.PIPE)
       output=proc.communicate(input=None)
       cols=int(output[0])
       proc=subprocess.Popen(["tput", "lines"],stdin=subprocess.PIPE,stdout=subprocess.PIPE)
       output=proc.communicate(input=None)
       rows=int(output[0])
       return (cols,rows)
    except:
       return None


def _getTerminalSize_linux():
    def ioctl_GWINSZ(fd):
        try:
            import fcntl, termios, struct, os
            cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,'1234'))
        except:
            return None
        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:
        try:
            cr = (env['LINES'], env['COLUMNS'])
        except:
            return None
    return int(cr[1]), int(cr[0])

if __name__ == "__main__":
    sizex,sizey=getTerminalSize()
    print  'width =',sizex,'height =',sizey

À partir de Python 3.3, il est simple: https://docs.python.org/3/library/ os.html #-la-interrogation taille-of-a-terminal

>>> import os
>>> ts = os.get_terminal_size()
>>> ts.lines
24
>>> ts.columns
80

Il est soit:

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

La fonction shutil est juste une enveloppe autour d'une os qui attire des erreurs et mettre en place une solution de repli, mais il a une mise en garde énorme - il se casse lorsque la tuyauterie , qui est une affaire assez énorme!.
Pour avoir obtenir la taille du terminal lorsque la tuyauterie utilisation os.get_terminal_size(0) à la place.

Le premier argument est un argument 0 indiquant que le descripteur de fichier stdin doit être utilisé au lieu de stdout par défaut. Nous voulons utiliser stdin parce que stdout se détache quand il est canalisé ce qui pose dans ce cas soulève une erreur ..
J'ai essayé de savoir quand serait-il logique d'utiliser stdout au lieu de l'argument de stdin et ne savent pas pourquoi un défaut ici.

Il semble qu'il y ait quelques problèmes avec ce code, Johannes:

  • getTerminalSize doit import os
  • ce qui est env? ressemble à os.environ.

En outre, pourquoi commutateur lines et cols avant de revenir? Si TIOCGWINSZ et stty disent tous les deux lines alors cols, dis-je laisser cette façon. Cela me confondre pour un bon 10 minutes avant de remarquer l'incohérence.

Sridhar, je n'ai pas cette erreur quand je LPRPDÉ sortie. Je suis sûr qu'il est d'être pris correctement dans l'essai, sauf.

pascals, "HHHH" ne fonctionne pas sur ma machine, mais "hh" fait. J'ai eu du mal à trouver la documentation pour cette fonction. On dirait qu'il est dépendant de la plateforme.

chochem, incorporé.

Voici ma version:

def getTerminalSize():
    """
    returns (lines:int, cols:int)
    """
    import os, struct
    def ioctl_GWINSZ(fd):
        import fcntl, termios
        return struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ, "1234"))
    # try stdin, stdout, stderr
    for fd in (0, 1, 2):
        try:
            return ioctl_GWINSZ(fd)
        except:
            pass
    # try os.ctermid()
    try:
        fd = os.open(os.ctermid(), os.O_RDONLY)
        try:
            return ioctl_GWINSZ(fd)
        finally:
            os.close(fd)
    except:
        pass
    # try `stty size`
    try:
        return tuple(int(x) for x in os.popen("stty size", "r").read().split())
    except:
        pass
    # try environment variables
    try:
        return tuple(int(os.getenv(var)) for var in ("LINES", "COLUMNS"))
    except:
        pass
    # i give up. return default.
    return (25, 80)

La plupart des implémentations Python 2 ici échouera s'il n'y a pas de terminal de contrôle lorsque vous appelez ce script. Vous pouvez vérifier sys.stdout.isatty () pour déterminer si cela est en fait un terminal, mais qui exclura un tas de cas, alors je crois que la façon la plus pythonique de comprendre la taille du terminal est d'utiliser le paquet malédictions builtin.

import curses
w = curses.initscr()
height, width = w.getmaxyx()

Je tentais la solution d'ici qui appelle à stty size:

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

Mais cela m'a échoué pour parce que je travaillais sur un script qui attend une entrée redirigée sur stdin et stty se plaindraient que « stdin est pas un terminal » dans ce cas.

Je suis en mesure de le faire fonctionner comme ceci:

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

@ reannual de réponse fonctionne bien, mais il y a un problème avec elle: os.popen href="https://docs.python.org/2/library/os.html#os.popen" rel="nofollow"> est maintenant dépréciée . Le module subprocess doit être utilisé à la place, voici donc une version du code de @ reannual qui utilise subprocess et répond directement à la question (en donnant la largeur de colonne directement comme int:

import subprocess

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

Testé sur OS X 10.9

Essayez "bénédictions"

Je cherchais la même chose. Il est très facile à utiliser et offre des outils pour la coloration, le style et le positionnement dans le terminal. Ce que vous avez besoin est aussi facile que:

from blessings import Terminal

t = Terminal()

w = t.width
h = t.height

Fonctionne comme un charme dans Linux. (Je ne suis pas sûr de MacOSX et Windows)

Télécharger et documentation

ou vous pouvez l'installer avec pip:

pip install blessings

Si vous utilisez Python 3.3 ou au-dessus, je vous recommande le comme déjà recommandé intégré get_terminal_size(). Toutefois, si vous êtes coincé avec une version plus ancienne et que vous voulez un moyen simple et multi-plateforme de le faire, vous pouvez utiliser asciimatics . Ce package prend en charge les versions de Python retour à 2.7 et utilise des options similaires à celles proposées ci-dessus pour obtenir la borne / taille de la console actuelle.

construire simplement votre classe Screen et utiliser la propriété dimensions pour obtenir la hauteur et la largeur. Cela a été prouvé à travailler sur Linux, Mac OS X et Windows.

Oh - et la divulgation complète ici. Je suis l'auteur, donc s'il vous plaît ne hésitez pas à ouvrir un nouveau problème si vous avez des problèmes pour obtenir que cela fonctionne

Voici une version qui devrait être compatible Linux et Solaris. Sur la base des messages et commments de madchine . Nécessite le module de sous-processus.

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')
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top