3

これは 2 つの部分からなる質問です。以下を参照してください。

  • テスターがいくつかのコマンドを手動で実行するために使用する、ある種のコンソールを作成する必要があります。モジュールは良い方法ですかcmd

以下は、cmdモジュールを使用してこれまでに作成したコードです。学習しようとしているだけで、これまでに2つの質問があります。

  • オートコンプリート機能が機能しないのはなぜですか? ダブル<TAB>すると何も得られず、カーソルは前方に移動します。オートコンプリート機能はデフォルトで提供されていませんか?

  • メソッドごとに間違った数の引数を処理する必要がありますか? メソッドが間違った数の引数で呼び出された場合、または引数で呼び出されるべきなのに呼び出されなかった場合に、メソッドの「ヘルプ」テキストが自動的に表示されるようにしたいと思います。

.

class InteractiveConsole(cmd.Cmd):
    """ Interactive command line """

    def __init__(self):
        cmd.Cmd.__init__(self)
        self.prompt = "=>> "
        self.intro = "Welcome to IRT console!"

    def do_hist(self, args):
        """Print a list of commands that have been entered"""
        print self._hist

    def do_exit(self, args):
        """Exits from the console"""
        return -1

    def do_help(self, args):
        """Get help on commands
           'help' or '?' with no arguments prints a list of commands for which help is available
           'help <command>' or '? <command>' gives help on <command>
        """
        # # The only reason to define this method is for the help text in the doc string
        cmd.Cmd.do_help(self, args)

    # # Override methods in Cmd object ##
    def preloop(self):
        """Initialization before prompting user for commands.
           Despite the claims in the Cmd documentaion, Cmd.preloop() is not a stub.
        """
        cmd.Cmd.preloop(self)  # # sets up command completion
        self._hist = []  # # No history yet
        self._locals = {}  # # Initialize execution namespace for user
        self._globals = {}

    def postloop(self):
        """Take care of any unfinished business.
           Despite the claims in the Cmd documentaion, Cmd.postloop() is not a stub.
        """
        cmd.Cmd.postloop(self)  # # Clean up command completion
        print "Exiting..."

    def precmd(self, line):
        """ This method is called after the line has been input but before
            it has been interpreted. If you want to modify the input line
            before execution (for example, variable substitution) do it here.
        """
        if line != '':
            self._hist += [ line.strip() ]
        return line

    def postcmd(self, stop, line):
        """If you want to stop the console, return something that evaluates to true.
           If you want to do some post command processing, do it here.
        """
        return stop

    def default(self, line):
        """Called on an input line when the command prefix is not recognized.
           In that case we execute the line as Python code.
        """
        try:
            exec(line) in self._locals, self._globals
        except Exception, e:
            print e.__class__, ":", e

    def emptyline(self):
        """Do nothing on empty input line"""
        pass





    def do_install(self, pathToBuild):
        """install [pathToBuild]
        install using the specified file"""
        if pathToBuild:
            print "installing %s" % pathToBuild
        else:
            print "<ERROR> You must specify the absolute path to a file which should be used!"


    def do_configure(self, pathToConfiguration):
        """configure [pathToConfiguration]
        configure using the specified file"""
        if pathToConfiguration:
            print "configuring %s" % pathToConfiguration
        else:
            print "<ERROR> You must specify the absolute path to a file which should be used!"
4

2 に答える 2

4

cmdドキュメントから:

オプションの引数completekeyreadline、補完キーの名前です。デフォルトはTabです。completekeyがなくNone、使用可能な場合readline、コマンドの補完は自動的に行われます。

readlineタブ補完が機能するには、利用可能にする必要があります。

コマンド メソッドは1 つの引数しかとらず、コマンド メソッド自体で引数の解析を行う必要があります。self.do_help()もちろん、必要に応じてまたはself.help_<cmd>()メソッドを呼び出すこともできます。

于 2013-07-19T12:10:29.720 に答える
1

最初の部分については、はい、cmd モジュールは使いやすく、Python の組み込みコマンド プロンプトに似た CLI を実装するのに十分強力であることがわかりました。

2 番目の部分の最初の質問では、現在の単語、行、開始、終了のインデックスを取得する complete_install(self, word, line, begindex, endindex) のようなメソッドを実装して、コマンド ラインを完了する方法をモジュールに指示する必要があります。行で、有効な補完を表す文字列のリストまたはタプルを返します。通常、現在の単語 (最初の引数) に基づいてリストを計算し、フィルター処理する必要があります。

たとえば、次のように実装されたログ レベルを設定するコマンド「ll」を使用します。

def complete_ll(self, a, ln, bi, ei):
    return tuple(
        k for k in logging._nameToLevel.keys()
        if k.casefold().find(a.casefold()) >= 0)

def do_ll(self, a):
    "Set or get debug level: DL [10 .. 50 | levelName]"
    def ll():
        n = log.getEffectiveLevel()
        return f"{logging.getLevelName(n)} ({n})"
    print(ll())
    if a:
        try:
            log.setLevel(eval(a.upper(), logging._nameToLevel))
            print("Logging level changed to", ll())
        except Exception as e:
            log.exception(f"{e}, value {a}", exc_info=1)

2番目の質問については、はい、「do_...」メソッドの引数の数、タイプ、および有効性を確認する必要があります。これは、例である程度行われています。もちろん、本当に役立つのであれば、その時点で「help_...」メソッドを呼び出すこともできます。

于 2020-04-18T14:24:59.307 に答える