软件编程_Python_shell

本文介绍了一个使用Python实现的跨平台命令行接口(CLI)设计,该设计支持自动补全功能,特别针对MacOSX进行了优化。文章详细展示了如何处理Python2和Python3的兼容性问题,包括字符串类型、输入函数、整数类型等,并提供了将整数转换为字节和从字节转换为整数的方法。此外,还展示了如何创建一个基本的CLI应用程序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#! /usr/bin/env python
# -*- coding: utf-8 -*-
import cmd
import sys


PYTHON3 = sys.version >= '3'

if PYTHON3:
    string_types = str

    def u(x):
        return x

    integer_types = (int, )

    input = input

    int_to_bytes = int.to_bytes
    int_from_bytes = int.from_bytes

else:
    string_types = basestring

    import codecs

    def u(x):
        return codecs.unicode_escape_decode(x)[0]

    integer_types = (int, long)

    input = raw_input

    # The 2 following function implementation extracted from the python-future
    # project
    import collections

    def int_to_bytes(integer, length, byteorder, signed=False):
        """
        Return an array of bytes representing an integer.
        The integer is represented using length bytes.  An OverflowError is
        raised if the integer is not representable with the given number of
        bytes.
        The byteorder argument determines the byte order used to represent the
        integer.  If byteorder is 'big', the most significant byte is at the
        beginning of the byte array.  If byteorder is 'little', the most
        significant byte is at the end of the byte array.  To request the
        native byte order of the host system, use `sys.byteorder' as the byte
        order value.
        The signed keyword-only argument determines whether two's complement is
        used to represent the integer.  If signed is False and a negative
        integer is given, an OverflowError is raised.
        """
        if length < 0:
            raise ValueError("length argument must be non-negative")
        if length == 0 and integer == 0:
            return bytes()
        if signed and integer < 0:
            bits = length * 8
            num = (2**bits) + integer
            if num <= 0:
                raise OverflowError("int too smal to convert")
        else:
            if integer < 0:
                raise OverflowError("can't convert negative int to unsigned")
            num = integer
        if byteorder not in ('little', 'big'):
            raise ValueError("byteorder must be either 'little' or 'big'")
        h = b'%x' % num
        s = bytes((b'0'*(len(h) % 2) + h).zfill(length*2).decode('hex'))
        if signed:
            high_set = s[0] & 0x80
            if integer > 0 and high_set:
                raise OverflowError("int too big to convert")
            if integer < 0 and not high_set:
                raise OverflowError("int too small to convert")
        if len(s) > length:
            raise OverflowError("int too big to convert")
        return s if byteorder == 'big' else s[::-1]

    def int_from_bytes(mybytes, byteorder='big', signed=False):
        """
        Return the integer represented by the given array of bytes.
        The mybytes argument must either support the buffer protocol or be an
        iterable object producing bytes.  Bytes and bytearray are examples of
        built-in objects that support the buffer protocol.
        The byteorder argument determines the byte order used to represent the
        integer.  If byteorder is 'big', the most significant byte is at the
        beginning of the byte array.  If byteorder is 'little', the most
        significant byte is at the end of the byte array.  To request the
        native byte order of the host system, use `sys.byteorder' as the byte
        order value.
        The signed keyword-only argument indicates whether two's complement is
        used to represent the integer.
        """
        if byteorder not in ('little', 'big'):
            raise ValueError("byteorder must be either 'little' or 'big'")
        if isinstance(mybytes, unicode):
            raise TypeError("cannot convert unicode objects to bytes")
        # mybytes can also be passed as a sequence of integers on Py3.
        # Test for this:
        elif isinstance(mybytes, collections.Iterable):
            mybytes = bytes(mybytes)
        b = mybytes if byteorder == 'big' else mybytes[::-1]
        if len(b) == 0:
            b = b'\x00'
        # The encode() method has been disabled by newbytes, but Py2's
        # str has it:
        num = int(b.encode('hex'), 16)
        if signed and (b[0] & 0x80):
            num = num - (2 ** (len(b)*8))
        return num


print(sys.platform)
if sys.platform == 'darwin':

    class Cmd(cmd.Cmd):

        # This has been patched to enable autocompletion on Mac OSX
        def cmdloop(self, intro=None):
            """Repeatedly issue a prompt, accept input, parse an initial prefix
            off the received input, and dispatch to action methods, passing them
            the remainder of the line as argument.
            """
            
            self.preloop()
            if self.use_rawinput and self.completekey:
                try:
                    import readline
                    self.old_completer = readline.get_completer()
                    readline.set_completer(self.complete)

                    if 'libedit' in readline.__doc__:
                        # readline linked to BSD libedit
                        if self.completekey == 'tab':
                            key = '^I'
                        else:
                            key = self.completekey
                        readline.parse_and_bind('bind %s rl_complete' % (key,))
                    else:
                        # readline linked to the real readline
                        readline.parse_and_bind(self.completekey + ': complete')

                except ImportError:
                    pass
            try:
                if intro is not None:
                    self.intro = intro
                if self.intro:
                    self.stdout.write(str(self.intro) + "\n")
                stop = None
                while not stop:
                    if self.cmdqueue:
                        line = self.cmdqueue.pop(0)
                    else:
                        if self.use_rawinput:
                            try:
                                line = input(self.prompt)
                            except EOFError:
                                line = 'EOF'
                        else:
                            self.stdout.write(self.prompt)
                            self.stdout.flush()
                            line = self.stdin.readline()
                            if not len(line):
                                line = 'EOF'
                            else:
                                line = line.rstrip('\r\n')
                    line = self.precmd(line)
                    stop = self.onecmd(line)
                    stop = self.postcmd(stop, line)
                self.postloop()
            finally:
                if self.use_rawinput and self.completekey:
                    try:
                        import readline
                        readline.set_completer(self.old_completer)
                    except ImportError:
                        pass
else:
    Cmd = cmd.Cmd


class MyShell(Cmd):
    """Shell example."""

    intro = '\nWelcome to my shell. Type help or ? to list commands.\n'
    prompt = '> '

    use_rawinput = True

    def __init__(self):
        Cmd.__init__(self)

    def do_list(self, args):
        """List all connected resources."""

        print('do_list:TODO')
                
    def do_exit(self, arg):
        """Exit the shell session."""

        print('do_exit:TODO')
        return True

    def do_EOF(self, arg):
        """.
        """
        return True

if __name__ == '__main__':
    try:
        MyShell().cmdloop()
    except KeyboardInterrupt:
        print("Exit processing")
    

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值