มีวิธีใดในไพ ธ อนที่จะกำหนดความกว้างของคอนโซลโดยทางโปรแกรมหรือไม่ ฉันหมายถึงจำนวนตัวอักษรที่พอดีในหนึ่งบรรทัดโดยไม่มีการตัดคำไม่ใช่ความกว้างของพิกเซลของหน้าต่าง
แก้ไข
กำลังมองหาโซลูชันที่ใช้งานได้กับ Linux
มีวิธีใดในไพ ธ อนที่จะกำหนดความกว้างของคอนโซลโดยทางโปรแกรมหรือไม่ ฉันหมายถึงจำนวนตัวอักษรที่พอดีในหนึ่งบรรทัดโดยไม่มีการตัดคำไม่ใช่ความกว้างของพิกเซลของหน้าต่าง
แก้ไข
กำลังมองหาโซลูชันที่ใช้งานได้กับ Linux
คำตอบ:
import os
rows, columns = os.popen('stty size', 'r').read().split()
ใช้คำสั่ง 'stty size' ซึ่งเป็นไปตามเธรดในรายการส่งเมลของ Python ซึ่งเป็นสากลที่สมเหตุสมผลบน linux มันเปิดคำสั่ง 'ขนาด stty' เป็นไฟล์ 'อ่าน' จากมันและใช้การแบ่งสตริงแบบง่ายเพื่อแยกพิกัด
ต่างจากค่า os.environ ["COLUMNS"] (ซึ่งฉันไม่สามารถเข้าถึงได้แม้จะใช้ bash เป็นเชลล์มาตรฐานของฉัน) ข้อมูลจะเป็นข้อมูลที่ทันสมัยในขณะที่ฉันเชื่อว่า os.environ ["COLUMNS"] ค่าจะใช้ได้เฉพาะในช่วงเวลาของการเปิดตัว python interpreter (สมมติว่าผู้ใช้ปรับขนาดหน้าต่างตั้งแต่นั้นมา)
(ดูคำตอบโดย @GringoSuave เกี่ยวกับวิธีการทำเช่นนี้กับ python 3.3+)
rows, columns = subprocess.check_output(['stty', 'size']).split()สั้นกว่าเล็กน้อยบวกกับกระบวนการย่อยคืออนาคต
                    rows, columns = subprocess.check_output(['stty', 'size']).decode().split()ถ้าคุณต้องการสตริง unicode สำหรับความเข้ากันได้ของ py2 / 3
                    ไม่แน่ใจว่าทำไมมันอยู่ในโมดูล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
การใช้งานในระดับต่ำอยู่ในโมดูลระบบปฏิบัติการ ยังใช้งานได้ใน Windows
ขณะนี้มี backport สำหรับ Python 3.2 และด้านล่าง:
python3.5ติดตั้งแล้ว
                    Inappropriate ioctl for deviceข้อผิดพลาด / คำเตือนหรือรับค่าทางเลือกที่กำหนดไว้ที่ 80
                    ใช้
import console
(width, height) = console.getTerminalSize()
print "Your terminal's width is: %d" % width
แก้ไข : โอ้ฉันขอโทษ นี่ไม่ใช่ lib มาตรฐานของไพ ธ อนนี่คือที่มาของ 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, h
hp และ hp ควรมีความกว้างและความสูงของพิกเซล แต่ไม่ใช่
fcntl.ioctl(sys.stdin.fileno(), ...
                    stdoutหรือstderrแทนstdinแม้ว่า stdinอาจเป็นท่อได้เป็นอย่างดี if not os.isatty(0): return float("inf")นอกจากนี้คุณยังอาจต้องการที่จะเพิ่มบรรทัดเช่น
                    ฉันค้นหารอบ ๆ และพบวิธีแก้ปัญหาสำหรับ 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
              มันทั้ง:
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 file descriptor แทนค่าดีฟอลต์ stdout เราต้องการใช้ stdin เพราะ stdout แยกตัวเองเมื่อมันถูก piped ซึ่งในกรณีนี้ทำให้เกิดข้อผิดพลาด
ฉันพยายามคิดออกว่าจะใช้ stdout แทนที่จะเป็นอาร์กิวเมนต์ stdin เมื่อไรและไม่รู้ว่าทำไมจึงเป็นค่าเริ่มต้นที่นี่
os.get_terminal_size()เปิดตัวใน Python 3.3
                    os.get_terminal_size(0)จะมีปัญหาหากคุณไปที่ stdin ลอง:echo x | python3 -c 'import os; print(os.get_terminal_size(0))'
                    เริ่มต้นที่ 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
              shutil.get_terminal_size() is the high-level function which should normally be used, os.get_terminal_size is the low-level implementation.
                    ดูเหมือนว่ามีปัญหาบางอย่างกับรหัสนั้น Johannes:
getTerminalSize ต้องการ import osenvอะไร os.environดูเหมือนว่านอกจากนี้ทำไมสลับlinesและcolsก่อนกลับมา ถ้าTIOCGWINSZและsttyทั้งคู่พูดเช่นlinesนั้นcolsฉันก็บอกว่าปล่อยไว้อย่างนั้น เรื่องนี้ทำให้ฉันสับสน 10 นาทีก่อนที่ฉันจะสังเกตเห็นความไม่ลงรอยกัน
Sridhar ฉันไม่ได้รับข้อผิดพลาดนั้นเมื่อฉันส่งออก pip ฉันค่อนข้างมั่นใจว่ามันถูกจับได้อย่างถูกต้องในการลองยกเว้น
ปาสกาล"HHHH"ไม่ทำงานบนเครื่องของฉัน แต่"hh"ทำ ฉันมีปัญหาในการค้นหาเอกสารสำหรับฟังก์ชั่นนั้น ดูเหมือนว่ามันขึ้นอยู่กับแพลตฟอร์ม
chochem จัดตั้งขึ้น
นี่คือรุ่นของฉัน:
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.stdout.isatty () เพื่อตรวจสอบว่านี่เป็นเทอร์มินัลหรือไม่ แต่จะแยกเคสออกเป็นจำนวนมากดังนั้นฉันเชื่อว่าวิธีที่ไพเราะที่สุดในการหาขนาดเทอร์มินัลคือการใช้แพคเกจ
import curses
w = curses.initscr()
height, width = w.getmaxyx()
              ฉันกำลังลองวิธีแก้ปัญหาจากที่นี่ซึ่งเรียกไปที่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
              @ คำตอบ reannual ทำงานได้ดี แต่มีปัญหากับมันจะเลิกตอนนี้os.popen  subprocessโมดูลควรจะนำมาใช้แทนเพื่อให้ที่นี่เป็นรุ่นของรหัส @ reannual ที่ใช้subprocessโดยตรงและตอบคำถาม (โดยการให้ความกว้างของคอลัมน์โดยตรงเป็นint:
import subprocess
columns = int(subprocess.check_output(['stty', 'size']).split()[1])
ทดสอบบน OS X 10.9
หากคุณใช้ Python 3.3 ขึ้นไปฉันขอแนะนำ built-in get_terminal_size()ตามที่แนะนำแล้ว แต่ถ้าคุณจะติดอยู่กับรุ่นเก่าและต้องการวิธีง่ายๆที่ข้ามแพลตฟอร์มการทำเช่นนี้คุณสามารถใช้asciimatics แพ็คเกจนี้รองรับเวอร์ชั่นของ Python กลับไปที่ 2.7 และใช้ตัวเลือกที่คล้ายกับที่แนะนำไว้ข้างต้นเพื่อรับขนาดเทอร์มินัล / คอนโซลปัจจุบัน
เพียงสร้างScreenชั้นเรียนของคุณและใช้dimensionsคุณสมบัตินี้เพื่อให้ได้ความสูงและความกว้าง สิ่งนี้ได้รับการพิสูจน์แล้วว่าทำงานบน Linux, OSX และ Windows
โอ้ - และการเปิดเผยอย่างสมบูรณ์ที่นี่: ฉันเป็นผู้เขียนดังนั้นโปรดเปิดประเด็นใหม่หากคุณมีปัญหาในการทำให้เรื่องนี้ทำงานได้
นี่คือรุ่นที่ควรใช้กับ Linux และ Solaris ขึ้นอยู่กับการโพสต์และ commments จากmadchine ต้องการโมดูลย่อย
def termize ():
    นำเข้า shlex กระบวนการย่อยอีกครั้ง
    output = subprocess.check_output (shlex.split ('/ bin / stty -a'))
    m = re.search ('rows \ D + (? P \ d +); คอลัมน์ \ D + (? P \ d +);', เอาต์พุต)
    ถ้า m:
        ส่งคืน m.group ('แถว'), m.group ('คอลัมน์')
    เพิ่ม OSError ('การตอบสนองที่ไม่ดี:% s'% (เอาต์พุต))
>>> เงื่อนไข ()
('40', '100')