mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-08 23:14:06 +08:00
131 lines
35 KiB
HTML
131 lines
35 KiB
HTML
<div class="body" role="main"><div class="section" id="module-cmd"><h1><span class="yiyi-st" id="yiyi-10">24.2。 <a class="reference internal" href="#module-cmd" title="cmd: Build line-oriented command interpreters."><code class="xref py py-mod docutils literal"><span class="pre">cmd</span></code></a> - 支持面向行的命令解释器</span></h1><p><span class="yiyi-st" id="yiyi-11"><strong>源代码:</strong> <a class="reference external" href="https://hg.python.org/cpython/file/3.5/Lib/cmd.py">Lib / cmd.py</a></span></p><p><span class="yiyi-st" id="yiyi-12"><a class="reference internal" href="#cmd.Cmd" title="cmd.Cmd"><code class="xref py py-class docutils literal"><span class="pre">Cmd</span></code></a>类提供了一个用于编写面向行的命令解释器的简单框架。</span><span class="yiyi-st" id="yiyi-13">这些对于测试套件,管理工具和原型通常是有用的,它们将被包装在更复杂的界面中。</span></p><dl class="class"><dt id="cmd.Cmd"><span class="yiyi-st" id="yiyi-14"> <em class="property">class </em><code class="descclassname">cmd.</code><code class="descname">Cmd</code><span class="sig-paren">(</span><em>completekey='tab'</em>, <em>stdin=None</em>, <em>stdout=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-15">A <a class="reference internal" href="#cmd.Cmd" title="cmd.Cmd"><code class="xref py py-class docutils literal"><span class="pre">Cmd</span></code></a>实例或子类实例是一个面向行的解释器框架。</span><span class="yiyi-st" id="yiyi-16">没有好的理由实例化<a class="reference internal" href="#cmd.Cmd" title="cmd.Cmd"><code class="xref py py-class docutils literal"><span class="pre">Cmd</span></code></a>本身;相反,它作为您定义的解释器类的超类是有用的,以便继承<a class="reference internal" href="#cmd.Cmd" title="cmd.Cmd"><code class="xref py py-class docutils literal"><span class="pre">Cmd</span></code></a>的方法并封装动作方法。</span></p><p><span class="yiyi-st" id="yiyi-17">可选参数<em>completekey</em>是完成键的<a class="reference internal" href="readline.html#module-readline" title="readline: GNU readline support for Python. (Unix)"><code class="xref py py-mod docutils literal"><span class="pre">readline</span></code></a>名称;它默认为<code class="kbd docutils literal"><span class="pre">Tab</span></code>。</span><span class="yiyi-st" id="yiyi-18">如果<em>completekey</em>不是<a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a>和<a class="reference internal" href="readline.html#module-readline" title="readline: GNU readline support for Python. (Unix)"><code class="xref py py-mod docutils literal"><span class="pre">readline</span></code></a>可用,则命令完成自动完成。</span></p><p><span class="yiyi-st" id="yiyi-19">可选参数<em>stdin</em>和<em>stdout</em>指定Cmd实例或子类实例将用于输入和输出的输入和输出文件对象。</span><span class="yiyi-st" id="yiyi-20">如果未指定,它们将默认为<a class="reference internal" href="sys.html#sys.stdin" title="sys.stdin"><code class="xref py py-data docutils literal"><span class="pre">sys.stdin</span></code></a>和<a class="reference internal" href="sys.html#sys.stdout" title="sys.stdout"><code class="xref py py-data docutils literal"><span class="pre">sys.stdout</span></code></a>。</span></p><p><span class="yiyi-st" id="yiyi-21">如果要使用给定的<em>stdin</em>,请确保将实例的<a class="reference internal" href="#cmd.Cmd.use_rawinput" title="cmd.Cmd.use_rawinput"><code class="xref py py-attr docutils literal"><span class="pre">use_rawinput</span></code></a>属性设置为<code class="docutils literal"><span class="pre">False</span></code>,否则<em>stdin 将被忽略。</em></span></p></dd></dl><div class="section" id="cmd-objects"><h2><span class="yiyi-st" id="yiyi-22">24.2.1. </span><span class="yiyi-st" id="yiyi-23">Cmd对象</span></h2><p><span class="yiyi-st" id="yiyi-24">A <a class="reference internal" href="#cmd.Cmd" title="cmd.Cmd"><code class="xref py py-class docutils literal"><span class="pre">Cmd</span></code></a>实例具有以下方法:</span></p><dl class="method"><dt id="cmd.Cmd.cmdloop"><span class="yiyi-st" id="yiyi-25"> <code class="descclassname">Cmd.</code><code class="descname">cmdloop</code><span class="sig-paren">(</span><em>intro=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-26">重复发出提示,接受输入,解析接收到的输入的初始前缀,并分派到动作方法,将其余行作为参数传递。</span></p><p><span class="yiyi-st" id="yiyi-27">可选参数是在第一个提示之前发出的横幅或介绍字符串(这将覆盖<a class="reference internal" href="#cmd.Cmd.intro" title="cmd.Cmd.intro"><code class="xref py py-attr docutils literal"><span class="pre">intro</span></code></a>类属性)。</span></p><p><span class="yiyi-st" id="yiyi-28">如果加载了<a class="reference internal" href="readline.html#module-readline" title="readline: GNU readline support for Python. (Unix)"><code class="xref py py-mod docutils literal"><span class="pre">readline</span></code></a>模块,则输入将自动继承<strong class="program">bash</strong>样历史列表编辑(例如,</span><span class="yiyi-st" id="yiyi-29"><code class="kbd docutils literal"><span class="pre">Control-P</span></code>滚动返回到最后一个命令,<code class="kbd docutils literal"><span class="pre">Control-N</span></code>转到下一个命令,<code class="kbd docutils literal"><span class="pre">Control-F</span></code> - 破坏性地,<code class="kbd docutils literal"><span class="pre">Control-B</span></code>非破坏性地将光标向左移动等。</span><span class="yiyi-st" id="yiyi-30">)。</span></p><p><span class="yiyi-st" id="yiyi-31">输入上的文件结尾以字符串<code class="docutils literal"><span class="pre">'EOF'</span></code>返回。</span></p><p><span class="yiyi-st" id="yiyi-32">当且仅当它具有方法<code class="xref py py-meth docutils literal"><span class="pre">do_foo()</span></code>时,解释器实例将识别命令名<code class="docutils literal"><span class="pre">foo</span></code>。</span><span class="yiyi-st" id="yiyi-33">作为特殊情况,以字符<code class="docutils literal"><span class="pre">'?'</span></code>开头的行</span><span class="yiyi-st" id="yiyi-34">被分派到方法<code class="xref py py-meth docutils literal"><span class="pre">do_help()</span></code>。</span><span class="yiyi-st" id="yiyi-35">作为另一种特殊情况,以字符<code class="docutils literal"><span class="pre">'!'</span></code>开头的行</span><span class="yiyi-st" id="yiyi-36">被分派到方法<code class="xref py py-meth docutils literal"><span class="pre">do_shell()</span></code>(如果定义了这样的方法)。</span></p><p><span class="yiyi-st" id="yiyi-37">当<a class="reference internal" href="#cmd.Cmd.postcmd" title="cmd.Cmd.postcmd"><code class="xref py py-meth docutils literal"><span class="pre">postcmd()</span></code></a>方法返回true值时,此方法将返回。</span><span class="yiyi-st" id="yiyi-38"><a class="reference internal" href="#cmd.Cmd.postcmd" title="cmd.Cmd.postcmd"><code class="xref py py-meth docutils literal"><span class="pre">postcmd()</span></code></a>的<em>stop</em>参数是命令的相应<code class="xref py py-meth docutils literal"><span class="pre">do_*()</span></code>方法的返回值。</span></p><p><span class="yiyi-st" id="yiyi-39">如果启用完成,则将自动完成命令,并且通过使用参数<em>文本</em>,<em>行</em>调用<code class="xref py py-meth docutils literal"><span class="pre">complete_foo()</span></code>完成命令args ,<em>begidx</em>和<em>endidx</em>。</span><span class="yiyi-st" id="yiyi-40"><em>text</em>是我们尝试匹配的字符串前缀:所有返回的匹配都必须以它开头。</span><span class="yiyi-st" id="yiyi-41"><em>行</em>是移除了前导空白的当前输入行,<em>begidx</em>和<em>endidx</em>是前缀文本的开始和结束索引,以根据参数在哪个位置提供不同的完成。</span></p><p><span class="yiyi-st" id="yiyi-42"><a class="reference internal" href="#cmd.Cmd" title="cmd.Cmd"><code class="xref py py-class docutils literal"><span class="pre">Cmd</span></code></a>的所有子类继承预定义的<code class="xref py py-meth docutils literal"><span class="pre">do_help()</span></code>。</span><span class="yiyi-st" id="yiyi-43">这个方法用参数<code class="docutils literal"><span class="pre">'bar'</span></code>调用,调用相应的方法<code class="xref py py-meth docutils literal"><span class="pre">help_bar()</span></code>,如果不存在,打印<code class="xref py py-meth docutils literal"><span class="pre">do_bar()</span></code>(如果可用)。</span><span class="yiyi-st" id="yiyi-44">没有参数,<code class="xref py py-meth docutils literal"><span class="pre">do_help()</span></code>列出所有可用的帮助主题(即,所有命令与相应的<code class="xref py py-meth docutils literal"><span class="pre">help_*()</span></code>方法或具有docstrings的命令)未记录的命令。</span></p></dd></dl><dl class="method"><dt id="cmd.Cmd.onecmd"><span class="yiyi-st" id="yiyi-45"> <code class="descclassname">Cmd.</code><code class="descname">onecmd</code><span class="sig-paren">(</span><em>str</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-46">解释参数,就像它已经响应提示输入。</span><span class="yiyi-st" id="yiyi-47">这可能被覆盖,但通常不需要;请参阅有用的执行钩子的<a class="reference internal" href="#cmd.Cmd.precmd" title="cmd.Cmd.precmd"><code class="xref py py-meth docutils literal"><span class="pre">precmd()</span></code></a>和<a class="reference internal" href="#cmd.Cmd.postcmd" title="cmd.Cmd.postcmd"><code class="xref py py-meth docutils literal"><span class="pre">postcmd()</span></code></a>方法。</span><span class="yiyi-st" id="yiyi-48">返回值是指示解释器对命令的解释是否应该停止的标志。</span><span class="yiyi-st" id="yiyi-49">如果命令<em>str</em>有<code class="xref py py-meth docutils literal"><span class="pre">do_*()</span></code>方法,则返回该方法的返回值,否则返回<a class="reference internal" href="#cmd.Cmd.default" title="cmd.Cmd.default"><code class="xref py py-meth docutils literal"><span class="pre">default()</span></code></a></span></p></dd></dl><dl class="method"><dt id="cmd.Cmd.emptyline"><span class="yiyi-st" id="yiyi-50"> <code class="descclassname">Cmd.</code><code class="descname">emptyline</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-51">响应提示输入空行时调用的方法。</span><span class="yiyi-st" id="yiyi-52">如果此方法未被覆盖,它将重复输入的最后一个非空命令。</span></p></dd></dl><dl class="method"><dt id="cmd.Cmd.default"><span class="yiyi-st" id="yiyi-53"> <code class="descclassname">Cmd.</code><code class="descname">default</code><span class="sig-paren">(</span><em>line</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-54">无法识别命令前缀时在输入行上调用的方法。</span><span class="yiyi-st" id="yiyi-55">如果此方法未覆盖,它将输出错误消息并返回。</span></p></dd></dl><dl class="method"><dt id="cmd.Cmd.completedefault"><span class="yiyi-st" id="yiyi-56"> <code class="descclassname">Cmd.</code><code class="descname">completedefault</code><span class="sig-paren">(</span><em>text</em>, <em>line</em>, <em>begidx</em>, <em>endidx</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-57">当没有特定于命令的<code class="xref py py-meth docutils literal"><span class="pre">complete_*()</span></code>方法可用时,调用完成输入行的方法。</span><span class="yiyi-st" id="yiyi-58">默认情况下,它返回一个空列表。</span></p></dd></dl><dl class="method"><dt id="cmd.Cmd.precmd"><span class="yiyi-st" id="yiyi-59"> <code class="descclassname">Cmd.</code><code class="descname">precmd</code><span class="sig-paren">(</span><em>line</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-60">在命令行<em>行</em>之前执行的Hook方法被解释,但是在生成并发出输入提示之后。</span><span class="yiyi-st" id="yiyi-61">此方法是<a class="reference internal" href="#cmd.Cmd" title="cmd.Cmd"><code class="xref py py-class docutils literal"><span class="pre">Cmd</span></code></a>中的存根;它存在被子类覆盖。</span><span class="yiyi-st" id="yiyi-62">返回值用作将由<a class="reference internal" href="#cmd.Cmd.onecmd" title="cmd.Cmd.onecmd"><code class="xref py py-meth docutils literal"><span class="pre">onecmd()</span></code></a>方法执行的命令; <a class="reference internal" href="#cmd.Cmd.precmd" title="cmd.Cmd.precmd"><code class="xref py py-meth docutils literal"><span class="pre">precmd()</span></code></a>实现可以重写命令或简单地返回<em>行</em>而不改变。</span></p></dd></dl><dl class="method"><dt id="cmd.Cmd.postcmd"><span class="yiyi-st" id="yiyi-63"> <code class="descclassname">Cmd.</code><code class="descname">postcmd</code><span class="sig-paren">(</span><em>stop</em>, <em>line</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-64">在命令分派完成后执行Hook方法。</span><span class="yiyi-st" id="yiyi-65">此方法是<a class="reference internal" href="#cmd.Cmd" title="cmd.Cmd"><code class="xref py py-class docutils literal"><span class="pre">Cmd</span></code></a>中的存根;它存在被子类覆盖。</span><span class="yiyi-st" id="yiyi-66"><em>行</em>是被执行的命令行,<em>停止</em>是指示在调用<a class="reference internal" href="#cmd.Cmd.postcmd" title="cmd.Cmd.postcmd"><code class="xref py py-meth docutils literal"><span class="pre">postcmd()</span></code></a>后是否终止执行的标志;这将是<a class="reference internal" href="#cmd.Cmd.onecmd" title="cmd.Cmd.onecmd"><code class="xref py py-meth docutils literal"><span class="pre">onecmd()</span></code></a>方法的返回值。</span><span class="yiyi-st" id="yiyi-67">此方法的返回值将用作对应于<em>stop</em>的内部标志的新值;返回false将导致解释继续。</span></p></dd></dl><dl class="method"><dt id="cmd.Cmd.preloop"><span class="yiyi-st" id="yiyi-68"> <code class="descclassname">Cmd.</code><code class="descname">preloop</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-69">当调用<a class="reference internal" href="#cmd.Cmd.cmdloop" title="cmd.Cmd.cmdloop"><code class="xref py py-meth docutils literal"><span class="pre">cmdloop()</span></code></a>时执行一次Hook方法。</span><span class="yiyi-st" id="yiyi-70">此方法是<a class="reference internal" href="#cmd.Cmd" title="cmd.Cmd"><code class="xref py py-class docutils literal"><span class="pre">Cmd</span></code></a>中的存根;它存在被子类覆盖。</span></p></dd></dl><dl class="method"><dt id="cmd.Cmd.postloop"><span class="yiyi-st" id="yiyi-71"> <code class="descclassname">Cmd.</code><code class="descname">postloop</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-72">当<a class="reference internal" href="#cmd.Cmd.cmdloop" title="cmd.Cmd.cmdloop"><code class="xref py py-meth docutils literal"><span class="pre">cmdloop()</span></code></a>即将返回时执行一次Hook方法。</span><span class="yiyi-st" id="yiyi-73">此方法是<a class="reference internal" href="#cmd.Cmd" title="cmd.Cmd"><code class="xref py py-class docutils literal"><span class="pre">Cmd</span></code></a>中的存根;它存在被子类覆盖。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-74"><a class="reference internal" href="#cmd.Cmd" title="cmd.Cmd"><code class="xref py py-class docutils literal"><span class="pre">Cmd</span></code></a>子类的实例有一些公共实例变量:</span></p><dl class="attribute"><dt id="cmd.Cmd.prompt"><span class="yiyi-st" id="yiyi-75"> <code class="descclassname">Cmd.</code><code class="descname">prompt</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-76">发出提示以征求输入。</span></p></dd></dl><dl class="attribute"><dt id="cmd.Cmd.identchars"><span class="yiyi-st" id="yiyi-77"> <code class="descclassname">Cmd.</code><code class="descname">identchars</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-78">命令前缀接受的字符串字符串。</span></p></dd></dl><dl class="attribute"><dt id="cmd.Cmd.lastcmd"><span class="yiyi-st" id="yiyi-79"> <code class="descclassname">Cmd.</code><code class="descname">lastcmd</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-80">显示的最后一个非空命令前缀。</span></p></dd></dl><dl class="attribute"><dt id="cmd.Cmd.cmdqueue"><span class="yiyi-st" id="yiyi-81"> <code class="descclassname">Cmd.</code><code class="descname">cmdqueue</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-82">队列输入行的列表。</span><span class="yiyi-st" id="yiyi-83">当需要新输入时,在<a class="reference internal" href="#cmd.Cmd.cmdloop" title="cmd.Cmd.cmdloop"><code class="xref py py-meth docutils literal"><span class="pre">cmdloop()</span></code></a>中检查cmdqueue列表;如果它是非空的,其元素将按顺序处理,如同在提示符处输入。</span></p></dd></dl><dl class="attribute"><dt id="cmd.Cmd.intro"><span class="yiyi-st" id="yiyi-84"> <code class="descclassname">Cmd.</code><code class="descname">intro</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-85">要作为简介或横幅发出的字符串。</span><span class="yiyi-st" id="yiyi-86">可以通过将<a class="reference internal" href="#cmd.Cmd.cmdloop" title="cmd.Cmd.cmdloop"><code class="xref py py-meth docutils literal"><span class="pre">cmdloop()</span></code></a>方法作为参数来覆盖。</span></p></dd></dl><dl class="attribute"><dt id="cmd.Cmd.doc_header"><span class="yiyi-st" id="yiyi-87"> <code class="descclassname">Cmd.</code><code class="descname">doc_header</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-88">如果帮助输出具有已记录命令的部分,则发出标题。</span></p></dd></dl><dl class="attribute"><dt id="cmd.Cmd.misc_header"><span class="yiyi-st" id="yiyi-89"> <code class="descclassname">Cmd.</code><code class="descname">misc_header</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-90">如果帮助输出具有其他帮助主题的部分(即,没有对应的<code class="xref py py-meth docutils literal"><span class="pre">do_*()</span></code>方法的<code class="xref py py-meth docutils literal"><span class="pre">help_*()</span></code>方法),则发出标题。</span></p></dd></dl><dl class="attribute"><dt id="cmd.Cmd.undoc_header"><span class="yiyi-st" id="yiyi-91"> <code class="descclassname">Cmd.</code><code class="descname">undoc_header</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-92">如果帮助输出具有未记录的命令的部分(即,没有相应的<code class="xref py py-meth docutils literal"><span class="pre">help_*()</span></code>方法的<code class="xref py py-meth docutils literal"><span class="pre">do_*()</span></code>方法),则发出标题。</span></p></dd></dl><dl class="attribute"><dt id="cmd.Cmd.ruler"><span class="yiyi-st" id="yiyi-93"> <code class="descclassname">Cmd.</code><code class="descname">ruler</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-94">用于在帮助消息标题下绘制分隔线的字符。</span><span class="yiyi-st" id="yiyi-95">如果为空,则不绘制标尺线。</span><span class="yiyi-st" id="yiyi-96">它默认为<code class="docutils literal"><span class="pre">'='</span></code>。</span></p></dd></dl><dl class="attribute"><dt id="cmd.Cmd.use_rawinput"><span class="yiyi-st" id="yiyi-97"> <code class="descclassname">Cmd.</code><code class="descname">use_rawinput</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-98">一个标志,默认为true。</span><span class="yiyi-st" id="yiyi-99">如果为true,则<a class="reference internal" href="#cmd.Cmd.cmdloop" title="cmd.Cmd.cmdloop"><code class="xref py py-meth docutils literal"><span class="pre">cmdloop()</span></code></a>使用<a class="reference internal" href="functions.html#input" title="input"><code class="xref py py-func docutils literal"><span class="pre">input()</span></code></a>显示提示并读取下一个命令;如果为false,则使用<code class="xref py py-meth docutils literal"><span class="pre">sys.stdout.write()</span></code>和<code class="xref py py-meth docutils literal"><span class="pre">sys.stdin.readline()</span></code>。</span><span class="yiyi-st" id="yiyi-100">(这意味着通过导入<a class="reference internal" href="readline.html#module-readline" title="readline: GNU readline support for Python. (Unix)"><code class="xref py py-mod docutils literal"><span class="pre">readline</span></code></a>,在支持它的系统上,解释器将自动支持<strong class="program">Emacs</strong> - 例如行编辑和命令历史击键。</span></p></dd></dl></div><div class="section" id="cmd-example"><h2><span class="yiyi-st" id="yiyi-101">24.2.2. </span><span class="yiyi-st" id="yiyi-102">Cmd示例</span></h2><p><span class="yiyi-st" id="yiyi-103"><a class="reference internal" href="#module-cmd" title="cmd: Build line-oriented command interpreters."><code class="xref py py-mod docutils literal"><span class="pre">cmd</span></code></a>模块主要用于构建允许用户以交互方式处理程序的自定义外壳。</span></p><p><span class="yiyi-st" id="yiyi-104">本节介绍如何在<a class="reference internal" href="turtle.html#module-turtle" title="turtle: An educational framework for simple graphics applications"><code class="xref py py-mod docutils literal"><span class="pre">turtle</span></code></a>模块中的几个命令构建shell的简单示例。</span></p><p><span class="yiyi-st" id="yiyi-105">使用名为<code class="xref py py-meth docutils literal"><span class="pre">do_forward()</span></code>的方法将基本龟图命令(例如<a class="reference internal" href="turtle.html#turtle.forward" title="turtle.forward"><code class="xref py py-meth docutils literal"><span class="pre">forward()</span></code></a>添加到<a class="reference internal" href="#cmd.Cmd" title="cmd.Cmd"><code class="xref py py-class docutils literal"><span class="pre">Cmd</span></code></a>子类中)。</span><span class="yiyi-st" id="yiyi-106">参数被转换为一个数字并被分派到龟模块。</span><span class="yiyi-st" id="yiyi-107">docstring在shell提供的帮助实用程序中使用。</span></p><p><span class="yiyi-st" id="yiyi-108">该示例还包括使用<a class="reference internal" href="#cmd.Cmd.precmd" title="cmd.Cmd.precmd"><code class="xref py py-meth docutils literal"><span class="pre">precmd()</span></code></a>方法实现的基本记录和回放设施,该方法负责将输入转换为小写并将命令写入文件。</span><span class="yiyi-st" id="yiyi-109"><code class="xref py py-meth docutils literal"><span class="pre">do_playback()</span></code>方法读取文件,并将记录的命令添加到<code class="xref py py-attr docutils literal"><span class="pre">cmdqueue</span></code>以立即播放:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">cmd</span><span class="o">,</span> <span class="nn">sys</span>
|
||
<span class="kn">from</span> <span class="nn">turtle</span> <span class="k">import</span> <span class="o">*</span>
|
||
|
||
<span class="k">class</span> <span class="nc">TurtleShell</span><span class="p">(</span><span class="n">cmd</span><span class="o">.</span><span class="n">Cmd</span><span class="p">):</span>
|
||
<span class="n">intro</span> <span class="o">=</span> <span class="s1">'Welcome to the turtle shell. Type help or ? to list commands.</span><span class="se">\n</span><span class="s1">'</span>
|
||
<span class="n">prompt</span> <span class="o">=</span> <span class="s1">'(turtle) '</span>
|
||
<span class="n">file</span> <span class="o">=</span> <span class="kc">None</span>
|
||
|
||
<span class="c1"># ----- basic turtle commands -----</span>
|
||
<span class="k">def</span> <span class="nf">do_forward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
||
<span class="s1">'Move the turtle forward by the specified distance: FORWARD 10'</span>
|
||
<span class="n">forward</span><span class="p">(</span><span class="o">*</span><span class="n">parse</span><span class="p">(</span><span class="n">arg</span><span class="p">))</span>
|
||
<span class="k">def</span> <span class="nf">do_right</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
||
<span class="s1">'Turn turtle right by given number of degrees: RIGHT 20'</span>
|
||
<span class="n">right</span><span class="p">(</span><span class="o">*</span><span class="n">parse</span><span class="p">(</span><span class="n">arg</span><span class="p">))</span>
|
||
<span class="k">def</span> <span class="nf">do_left</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
||
<span class="s1">'Turn turtle left by given number of degrees: LEFT 90'</span>
|
||
<span class="n">left</span><span class="p">(</span><span class="o">*</span><span class="n">parse</span><span class="p">(</span><span class="n">arg</span><span class="p">))</span>
|
||
<span class="k">def</span> <span class="nf">do_goto</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
||
<span class="s1">'Move turtle to an absolute position with changing orientation. GOTO 100 200'</span>
|
||
<span class="n">goto</span><span class="p">(</span><span class="o">*</span><span class="n">parse</span><span class="p">(</span><span class="n">arg</span><span class="p">))</span>
|
||
<span class="k">def</span> <span class="nf">do_home</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
||
<span class="s1">'Return turtle to the home position: HOME'</span>
|
||
<span class="n">home</span><span class="p">()</span>
|
||
<span class="k">def</span> <span class="nf">do_circle</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
||
<span class="s1">'Draw circle with given radius an options extent and steps: CIRCLE 50'</span>
|
||
<span class="n">circle</span><span class="p">(</span><span class="o">*</span><span class="n">parse</span><span class="p">(</span><span class="n">arg</span><span class="p">))</span>
|
||
<span class="k">def</span> <span class="nf">do_position</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
||
<span class="s1">'Print the current turle position: POSITION'</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s1">'Current position is </span><span class="si">%d</span><span class="s1"> </span><span class="si">%d</span><span class="se">\n</span><span class="s1">'</span> <span class="o">%</span> <span class="n">position</span><span class="p">())</span>
|
||
<span class="k">def</span> <span class="nf">do_heading</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
||
<span class="s1">'Print the current turle heading in degrees: HEADING'</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s1">'Current heading is </span><span class="si">%d</span><span class="se">\n</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">heading</span><span class="p">(),))</span>
|
||
<span class="k">def</span> <span class="nf">do_color</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
||
<span class="s1">'Set the color: COLOR BLUE'</span>
|
||
<span class="n">color</span><span class="p">(</span><span class="n">arg</span><span class="o">.</span><span class="n">lower</span><span class="p">())</span>
|
||
<span class="k">def</span> <span class="nf">do_undo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
||
<span class="s1">'Undo (repeatedly) the last turtle action(s): UNDO'</span>
|
||
<span class="k">def</span> <span class="nf">do_reset</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
||
<span class="s1">'Clear the screen and return turtle to center: RESET'</span>
|
||
<span class="n">reset</span><span class="p">()</span>
|
||
<span class="k">def</span> <span class="nf">do_bye</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
||
<span class="s1">'Stop recording, close the turtle window, and exit: BYE'</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s1">'Thank you for using Turtle'</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
||
<span class="n">bye</span><span class="p">()</span>
|
||
<span class="k">return</span> <span class="kc">True</span>
|
||
|
||
<span class="c1"># ----- record and playback -----</span>
|
||
<span class="k">def</span> <span class="nf">do_record</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
||
<span class="s1">'Save future commands to filename: RECORD rose.cmd'</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">file</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span>
|
||
<span class="k">def</span> <span class="nf">do_playback</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">):</span>
|
||
<span class="s1">'Playback commands from a file: PLAYBACK rose.cmd'</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
||
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">cmdqueue</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">splitlines</span><span class="p">())</span>
|
||
<span class="k">def</span> <span class="nf">precmd</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">line</span><span class="p">):</span>
|
||
<span class="n">line</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">file</span> <span class="ow">and</span> <span class="s1">'playback'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">line</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">file</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">line</span>
|
||
<span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">file</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">file</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">file</span> <span class="o">=</span> <span class="kc">None</span>
|
||
|
||
<span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span>
|
||
<span class="s1">'Convert a series of zero or more numbers to an argument tuple'</span>
|
||
<span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">()))</span>
|
||
|
||
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
|
||
<span class="n">TurtleShell</span><span class="p">()</span><span class="o">.</span><span class="n">cmdloop</span><span class="p">()</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-110">下面是一个带有龟壳的示例会话,显示帮助功能,使用空行重复命令,以及简单的记录和回放设施:</span></p><div class="highlight-none"><div class="highlight"><pre><span></span>Welcome to the turtle shell. Type help or ? to list commands.
|
||
|
||
(turtle) ?
|
||
|
||
Documented commands (type help <topic>):
|
||
========================================
|
||
bye color goto home playback record right
|
||
circle forward heading left position reset undo
|
||
|
||
(turtle) help forward
|
||
Move the turtle forward by the specified distance: FORWARD 10
|
||
(turtle) record spiral.cmd
|
||
(turtle) position
|
||
Current position is 0 0
|
||
|
||
(turtle) heading
|
||
Current heading is 0
|
||
|
||
(turtle) reset
|
||
(turtle) circle 20
|
||
(turtle) right 30
|
||
(turtle) circle 40
|
||
(turtle) right 30
|
||
(turtle) circle 60
|
||
(turtle) right 30
|
||
(turtle) circle 80
|
||
(turtle) right 30
|
||
(turtle) circle 100
|
||
(turtle) right 30
|
||
(turtle) circle 120
|
||
(turtle) right 30
|
||
(turtle) circle 120
|
||
(turtle) heading
|
||
Current heading is 180
|
||
|
||
(turtle) forward 100
|
||
(turtle)
|
||
(turtle) right 90
|
||
(turtle) forward 100
|
||
(turtle)
|
||
(turtle) right 90
|
||
(turtle) forward 400
|
||
(turtle) right 90
|
||
(turtle) forward 500
|
||
(turtle) right 90
|
||
(turtle) forward 400
|
||
(turtle) right 90
|
||
(turtle) forward 300
|
||
(turtle) playback spiral.cmd
|
||
Current position is 0 0
|
||
|
||
Current heading is 0
|
||
|
||
Current heading is 180
|
||
|
||
(turtle) bye
|
||
Thank you for using Turtle
|
||
</pre></div></div></div></div></div> |