14 ответов:
import os rows, columns = os.popen('stty size', 'r').read().split()использует команду "stty size", которая в соответствии с нить в списке рассылки python достаточно универсален в linux. Он открывает команду "stty size" в виде файла, "читает" из него и использует простое разделение строк для разделения координат.
в отличие от операционной системы.значение environ ["столбцы"] (к которому я не могу получить доступ, несмотря на использование bash в качестве моей стандартной оболочки) данные также будут актуальными, тогда как я считаю, что ОС.environ ["столбцы"] значение будет только действительны на момент запуска интерпретатора Python (предположим, что пользователь изменил размер окна с тех пор).
не уверен, почему он находится в модуле
shutil, но он приземлился там в Python 3.3, запрос размера выходного терминала:>>> import shutil >>> shutil.get_terminal_size((80, 20)) # pass fallback os.terminal_size(columns=87, lines=23) # returns a named-tupleреализация низкого уровня находится в модуле ОС.
теперь доступен backport для Python 3.2 и ниже:
использовать
import console (width, height) = console.getTerminalSize() print "Your terminal's width is: %d" % widthEDIT: ой, простите. Это не стандартный lib python, вот источник console.py (я не знаю, откуда это).
модуль, кажется, работает так: он проверяет, если
termcapесть в наличии, если да. Он использует это; если нет, он проверяет, поддерживает ли терминал специальныйioctlвызов и это тоже не работает, он проверяет переменные среды, которые некоторые оболочки экспортируют для этого. Это, вероятно, будет работать на 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])
код выше не вернул правильный результат на моем linux, потому что winsize-struct имеет 4 неподписанных шорты, а не 2 подписанных шорты:
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, hhp и hp должны содержать ширину и высоту пикселя, но не делают.
Я искал вокруг и нашел решение для Windows по адресу :
http://code.activestate.com/recipes/440694-determine-size-of-console-window-on-windows/
и решение для Linux здесь.
Итак, вот версия, которая работает как на linux, os x и 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
начиная с Python 3.3 это прямо вперед: https://docs.python.org/3/library/os.html#querying-the-size-of-a-terminal
>>> import os >>> ts = os.get_terminal_size() >>> ts.lines 24 >>> ts.columns 80
похоже, что есть некоторые проблемы с этим кодом, Йоханнес:
getTerminalSizeнужноimport os- что это
env? выглядит какos.environ.кроме того, зачем переходить
linesиcolsперед возвращением? ЕслиTIOCGWINSZиsttyкак сказатьlinesзатемcols, Я говорю оставить его таким образом. Это смутило меня в течение хороших 10 минут, прежде чем я заметил несоответствие.Шридхар, я не получил эту ошибку, когда я трубил выход. Я почти уверен, что он был пойман правильно в попытке-за исключением.
Паскаль,
"HHHH"не работает на моей машине, но"hh"делает. У меня были проблемы с поиском документации для этой функции. Похоже, что это зависит от платформы.chochem, incorporated.
вот мой вариант:
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)
многие из реализаций Python 2 здесь потерпят неудачу, если при вызове этого скрипта не будет управляющего терминала. Вы можете проверить sys.стандартный вывод.isatty () чтобы определить, является ли это на самом деле терминалом, но это исключит кучу случаев, поэтому я считаю, что самый простой способ выяснить размер терминала-использовать встроенный пакет curses.
import curses w = curses.initscr() height, width = w.getmaxyx()
либо:
import os columns, rows = os.get_terminal_size(0) # or import shutil columns, rows = shutil.get_terminal_size()The .
первый аргумент
0- это аргумент, указывающий на то, что вместо стандартного stdout следует использовать дескриптор файла stdin. Мы хотим использовать stdin, потому что stdout отсоединяется, когда он передается по конвейеру, который в этом случае вызывает ошибку..
Я попытался выяснить, когда имеет смысл использовать stdout вместо аргумента stdin и понятия не имею, почему он здесь по умолчанию.
@reannual ответ работает хорошо, но есть проблема с ним:
os.popenтеперь не рекомендуется. Элемент , поэтому вот версия кода @reannual, которая используетsubprocessи непосредственно отвечает на вопрос (давая ширину столбца непосредственно какint:import subprocess columns = int(subprocess.check_output(['stty', 'size']).split()[1])протестировано на OS X 10.9
Я пытался решить отсюда, что вызывает к
stty size: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()
попробовать "благословения"
Я искал то же самое. Он очень прост в использовании и предлагает инструменты для окраски, укладки и позиционирования в терминале. То, что вам нужно, так же просто, как:
from blessings import Terminal t = Terminal() w = t.width h = t.heightработает как шарм в Linux. (Я не уверен в MacOSX и Windows)
загрузка и документация здесь
или вы можете установить его с помощью pip:
pip install blessings
Если вы используете Python 3.3 или выше, я бы рекомендовал встроенный
get_terminal_size()Как уже было рекомендовано. Однако если вы застряли с более старой версией и хотите простой, кросс-платформенный способ сделать это, вы можете использовать asciimatics. Этот пакет поддерживает версии Python до 2.7 и использует аналогичные параметры, предложенные выше, чтобы получить текущий размер терминала/консоли.просто построить свой
Screenклассе и использоватьdimensionsсвойство для получения высоты и ширина. Это было доказано, чтобы работать на Linux, OSX и Windows.О-и полное раскрытие здесь: я автор, поэтому, пожалуйста, не стесняйтесь открывать новый выпуск, Если у вас есть какие-либо проблемы с получением этой работы.
вот версия, которая должна быть совместима с 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')
Comments