uTools-Manuals/docs/python/xmlrpc.client.html
2019-04-21 11:50:48 +08:00

154 lines
62 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div class="body" role="main"><div class="section" id="module-xmlrpc.client"><h1><span class="yiyi-st" id="yiyi-10">21.26.<a class="reference internal" href="#module-xmlrpc.client" title="xmlrpc.client: XML-RPC client access."><code class="xref py py-mod docutils literal"><span class="pre">xmlrpc.client</span></code></a>-- XML_RPC客户端进程</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/xmlrpc/client.py">Lib / xmlrpc / client.py</a></span></p><p><span class="yiyi-st" id="yiyi-12">XML-RPC是一种使用通过HTTP传递信息的XML作为传输工具的远程过程调用方法。</span><span class="yiyi-st" id="yiyi-13">通过使用这个模块客户端可以调用远程服务器上的参数服务器由URI命名并返回结构化数据的方法。</span><span class="yiyi-st" id="yiyi-14">此模块支持编写XML-RPC客户端代码; 它还可以处理所有符合Python对象特点的项目和XML之间转换的细节。</span></p><div class="admonition warning"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-15">警告</span></p><p class="last"><span class="yiyi-st" id="yiyi-16">The <a class="reference internal" href="#module-xmlrpc.client" title="xmlrpc.client: XML-RPC client access."><code class="xref py py-mod docutils literal"><span class="pre">xmlrpc.client</span></code></a> 模块对于恶意构造的数据不安全</span><span class="yiyi-st" id="yiyi-17">如果需要解析不受信任或未经身份验证的数据请参阅XML漏洞。 <a class="reference internal" href="xml.html#xml-vulnerabilities"><span>XML vulnerabilities</span></a>.</span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-18"><span class="versionmodified">在 3.5版本中的变化:</span>For HTTPS URIs, <a class="reference internal" href="#module-xmlrpc.client" title="xmlrpc.client: XML-RPC client access."><code class="xref py py-mod docutils literal"><span class="pre">xmlrpc.client</span></code></a> 现在默认的进行验证和hostname检查</span></p></div><dl class="class"><dt id="xmlrpc.client.ServerProxy"><span class="yiyi-st" id="yiyi-19"> <em class="property">class </em><code class="descclassname">xmlrpc.client.</code><code class="descname">ServerProxy</code><span class="sig-paren">(</span><em>uri</em>, <em>transport=None</em>, <em>encoding=None</em>, <em>verbose=False</em>, <em>allow_none=False</em>, <em>use_datetime=False</em>, <em>use_builtin_types=False</em>, <em>*</em>, <em>context=None</em><span class="sig-paren">)</span></span></dt><dd><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-20"><span class="versionmodified">在3.3版本中的变化:</span>The <em>use_builtin_types</em> 被添加.</span></p></div><p><span class="yiyi-st" id="yiyi-21"><a class="reference internal" href="#xmlrpc.client.ServerProxy" title="xmlrpc.client.ServerProxy"><code class="xref py py-class docutils literal"><span class="pre">ServerProxy</span></code></a>实例是管理与远程XML-RPC服务器通信的对象。</span><span class="yiyi-st" id="yiyi-22">所需的第一个参数是URI统一资源指示符通常是服务器的URL。</span><span class="yiyi-st" id="yiyi-23">可选的第二个参数是传输协议实例;默认情况下它是httpsURL的内部<code class="xref py py-class docutils literal"><span class="pre">SafeTransport</span></code> 实例否则为内部其他的HTTP传输<code class="xref py py-class docutils literal"><span class="pre">Transport</span></code> 实例</span><span class="yiyi-st" id="yiyi-24">可选的第三个参数是编码方式默认为UTF-8UTF-88-bit Unicode Transformation Format是一种针对Unicode的可变长度字符编码又称万国码</span><span class="yiyi-st" id="yiyi-25">可选的第四个参数是调试标志。</span></p><p><span class="yiyi-st" id="yiyi-26">以下参数控制返回的代理服务器实例的使用。</span><span class="yiyi-st" id="yiyi-27"><em>allow_none</em> 是truePython常量<code class="docutils literal"><span class="pre">None</span></code>将被转换为XML;此时的python默认行为是由于<code class="docutils literal"><span class="pre">None</span></code>而抛出的<a class="reference internal" href="exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal"><span class="pre">TypeError</span></code></a>.</span><span class="yiyi-st" id="yiyi-28">这是对XML-RPC规范的常用扩展但不是所有的客户端和服务器都支持有关说明请参阅<a class="reference external" href="https://web.archive.org/web/20130120074804/http://ontosys.com/xml-rpc/extensions.php">http://ontosys.com/xml-rpc/extensions.php</a></span><span class="yiyi-st" id="yiyi-29"><em>use_builtin_types</em>标志可用于使日期/时间值显示为<a class="reference internal" href="datetime.html#datetime.datetime" title="datetime.datetime"><code class="xref py py-class docutils literal"><span class="pre">datetime.datetime</span></code></a>的对象,二进制数据显示为<a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a>对象默认情况下此标志为false。</span><span class="yiyi-st" id="yiyi-30"><a class="reference internal" href="datetime.html#datetime.datetime" title="datetime.datetime"><code class="xref py py-class docutils literal"><span class="pre">datetime.datetime</span></code></a><a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a><a class="reference internal" href="functions.html#bytearray" title="bytearray"><code class="xref py py-class docutils literal"><span class="pre">bytearray</span></code></a>对象可以传递给调用。</span><span class="yiyi-st" id="yiyi-31">过时的<em>use_datetime</em>标志与<em>use_builtin_types</em>类似,但它仅适用于日期/时间值。</span></p><p><span class="yiyi-st" id="yiyi-32">HTTP和HTTPS传输均支持HTTP基本身份验证的URL语法扩展<code class="docutils literal"><span class="pre">http// userpass @ hostport / path</span></code></span><span class="yiyi-st" id="yiyi-33"><code class="docutils literal"><span class="pre">userpass</span></code>部分将被base64编码为HTTP“授权”头文件并在调用XML-RPC方法时作为连接过程的一部分发送到远程服务器。</span><span class="yiyi-st" id="yiyi-34">如果远程服务器需要基本身份验证用户和密码,则只需使用此选项。</span><span class="yiyi-st" id="yiyi-35">如果提供了HTTPS网址<em>context</em>可能是<a class="reference internal" href="ssl.html#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal"><span class="pre">ssl.SSLContext</span></code></a>并配置底层HTTPS连接的SSL设置。</span></p><p><span class="yiyi-st" id="yiyi-36">返回的实例是一个代理对象其方法可用于调用远程服务器上的相应RPC调用。</span><span class="yiyi-st" id="yiyi-37">如果远程服务器支持自检API则代理还可以用于向远程服务器查询其支持的方法服务发现和获取其他与服务器关联的元数据。</span></p><p><span class="yiyi-st" id="yiyi-38">符合的类型(例如</span><span class="yiyi-st" id="yiyi-39">可以通过XML编组包括以下除非另有说明它们被解组为同一个Python类型</span></p><table border="1" class="docutils"><thead valign="bottom"><tr class="row-odd"><th class="head"><span class="yiyi-st" id="yiyi-40">XML-RPC类型</span></th><th class="head"><span class="yiyi-st" id="yiyi-41">Python类型</span></th></tr></thead><tbody valign="top"><tr class="row-even"><td><span class="yiyi-st" id="yiyi-42"><code class="docutils literal"><span class="pre">boolean</span></code></span></td><td><span class="yiyi-st" id="yiyi-43"><a class="reference internal" href="functions.html#bool" title="bool"><code class="xref py py-class docutils literal"><span class="pre">bool</span></code></a></span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-44"><code class="docutils literal"><span class="pre">int</span></code><code class="docutils literal"><span class="pre">i4</span></code></span></td><td><span class="yiyi-st" id="yiyi-45"><a class="reference internal" href="functions.html#int" title="int"><code class="xref py py-class docutils literal"><span class="pre">int</span></code></a>,范围从-2147483648到2147483647。</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-46"><code class="docutils literal"><span class="pre">double</span></code></span></td><td><span class="yiyi-st" id="yiyi-47"><a class="reference internal" href="functions.html#float" title="float"><code class="xref py py-class docutils literal"><span class="pre">float</span></code></a></span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-48"><code class="docutils literal"><span class="pre">string</span></code></span></td><td><span class="yiyi-st" id="yiyi-49"><a class="reference internal" href="stdtypes.html#str" title="str"><code class="xref py py-class docutils literal"><span class="pre">str</span></code></a></span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-50"><code class="docutils literal"><span class="pre">array</span></code></span></td><td><span class="yiyi-st" id="yiyi-51"><a class="reference internal" href="stdtypes.html#list" title="list"><code class="xref py py-class docutils literal"><span class="pre">list</span></code></a><a class="reference internal" href="stdtypes.html#tuple" title="tuple"><code class="xref py py-class docutils literal"><span class="pre">tuple</span></code></a></span><span class="yiyi-st" id="yiyi-52">数组以<a class="reference internal" href="stdtypes.html#list" title="list"><code class="xref py py-class docutils literal"><span class="pre">lists</span></code></a>返回。</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-53"><code class="docutils literal"><span class="pre">struct</span></code></span></td><td><span class="yiyi-st" id="yiyi-54"><a class="reference internal" href="stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal"><span class="pre">dict</span></code></a></span><span class="yiyi-st" id="yiyi-55">键必须是字符串,值可以是任何合适的类型。</span><span class="yiyi-st" id="yiyi-56">可以传递用户定义类的对象;只传输其<a class="reference internal" href="stdtypes.html#object.__dict__" title="object.__dict__"><code class="xref py py-attr docutils literal"><span class="pre">__ dict __</span></code></a>属性。</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-57"><code class="docutils literal"><span class="pre">dateTime.iso8601</span></code></span></td><td><span class="yiyi-st" id="yiyi-58"><a class="reference internal" href="#xmlrpc.client.DateTime" title="xmlrpc.client.DateTime"><code class="xref py py-class docutils literal"><span class="pre">DateTime</span></code></a><a class="reference internal" href="datetime.html#datetime.datetime" title="datetime.datetime"><code class="xref py py-class docutils literal"><span class="pre">datetime.datetime</span></code></a></span><span class="yiyi-st" id="yiyi-59">返回类型取决于<em>use_builtin_types</em><em>use_datetime</em>两个数据的值。</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-60"><code class="docutils literal"><span class="pre">base64</span></code></span></td><td><span class="yiyi-st" id="yiyi-61"><a class="reference internal" href="#xmlrpc.client.Binary" title="xmlrpc.client.Binary"><code class="xref py py-class docutils literal"><span class="pre">Binary</span></code></a><a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a><a class="reference internal" href="functions.html#bytearray" title="bytearray"><code class="xref py py-class docutils literal"><span class="pre">bytearray</span></code></a></span><span class="yiyi-st" id="yiyi-62">返回类型取决于<em>use_builtin_types</em>数据的值。</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-63"><code class="docutils literal"><span class="pre">nil</span></code></span></td><td><span class="yiyi-st" id="yiyi-64"><code class="docutils literal"><span class="pre">None</span></code>常数。</span><span class="yiyi-st" id="yiyi-65">仅当<em>allow_none</em>为true时才允许传递。</span></td></tr></tbody></table><p><span class="yiyi-st" id="yiyi-66">这是XML-RPC支持的全套数据类型。</span><span class="yiyi-st" id="yiyi-67">方法调用也可以引发用于发信号通知XML-RPC服务器错误的特殊<a class="reference internal" href="#xmlrpc.client.Fault" title="xmlrpc.client.Fault"><code class="xref py py-exc docutils literal"><span class="pre">Fault</span></code></a>实例或者用于在HTTP / HTTPS传输层中用信号通知错误的<a class="reference internal" href="#xmlrpc.client.ProtocolError" title="xmlrpc.client.ProtocolError"><code class="xref py py-exc docutils literal"><span class="pre">ProtocolError</span></code></a></span><span class="yiyi-st" id="yiyi-68"><a class="reference internal" href="#xmlrpc.client.Fault" title="xmlrpc.client.Fault"><code class="xref py py-exc docutils literal"><span class="pre">故障</span></code></a><a class="reference internal" href="#xmlrpc.client.ProtocolError" title="xmlrpc.client.ProtocolError"><code class="xref py py-exc docutils literal"><span class="pre">ProtocolError</span></code></a>都源自一个名为<code class="xref py py-exc docutils literal"><span class="pre">错误</span></code>的基类。</span><span class="yiyi-st" id="yiyi-69">请注意xmlrpc客户端模块当前不封装并且发送内置类型的子类的实例。</span></p><p><span class="yiyi-st" id="yiyi-70">当传递字符串时,服务器会自动的避开<code class="docutils literal"><span class="pre">&lt;</span></code>, <code class="docutils literal"><span class="pre">&gt;</span></code>,和<code class="docutils literal"><span class="pre">&amp;</span></code>中所带的字符串</span><span class="yiyi-st" id="yiyi-71">但是调用者有责任确保字符串中没有XML中不允许使用的字符例如ASCII值在0到31之间的控制字符当然是tab换行符和回车符除外。如果含有违禁字符将导致XML-RPC请求不到格式良好的XML。</span><span class="yiyi-st" id="yiyi-72">如果您必须通过XML-RPC传递任意字节请使用<a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a><a class="reference internal" href="functions.html#bytearray" title="bytearray"><code class="xref py py-class docutils literal"><span class="pre">bytearray</span></code></a>类或下面描述的<a class="reference internal" href="#xmlrpc.client.Binary" title="xmlrpc.client.Binary"><code class="xref py py-class docutils literal"><span class="pre">Binary</span></code></a>包装类。</span></p><p><span class="yiyi-st" id="yiyi-73"><code class="xref py py-class docutils literal"><span class="pre">Server</span></code>作为<a class="reference internal" href="#xmlrpc.client.ServerProxy" title="xmlrpc.client.ServerProxy"><code class="xref py py-class docutils literal"><span class="pre">ServerProxy</span></code></a>的别名保留,以实现向后的兼容性。</span><span class="yiyi-st" id="yiyi-74">新代码应使用<a class="reference internal" href="#xmlrpc.client.ServerProxy" title="xmlrpc.client.ServerProxy"><code class="xref py py-class docutils literal"><span class="pre">ServerProxy</span></code></a></span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-75"><span class="versionmodified">在版本3.5中已更改:</span>添加了<em>Context</em>参数。</span></p></div></dd></dl><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-76">也可以看看</span></p><dl class="last docutils"><dt><span class="yiyi-st" id="yiyi-77"><a class="reference external" href="http://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html">XML-RPC HOWTO</a></span></dt><dd><span class="yiyi-st" id="yiyi-78">可以在几种语言中很好的描述XML-RPC文件的参数。</span><span class="yiyi-st" id="yiyi-79">包含XML-RPC客户端开发人员需要知道的几乎所有内容。</span></dd><dt><span class="yiyi-st" id="yiyi-80"><a class="reference external" href="http://xmlrpc-c.sourceforge.net/introspection.html">XML-RPC内省</a></span></dt><dd><span class="yiyi-st" id="yiyi-81">描述用于内省的XML-RPC协议扩展。</span></dd><dt><span class="yiyi-st" id="yiyi-82"><a class="reference external" href="http://xmlrpc.scripting.com/spec.html">XML-RPC规范</a></span></dt><dd><span class="yiyi-st" id="yiyi-83">官方规格。</span></dd><dt><span class="yiyi-st" id="yiyi-84"><a class="reference external" href="http://effbot.org/zone/xmlrpc-errata.htm">非正式XML-RPC错误</a></span></dt><dd><span class="yiyi-st" id="yiyi-85">Fredrik Lundh的“非官方勘误旨在澄清XML-RPC规范中的某些细节以及设计在自己的XML-RPC实现时使用”最佳实践“的提示。</span></dd></dl></div><div class="section" id="serverproxy-objects"><h2><span class="yiyi-st" id="yiyi-86">21.26.1. </span><span class="yiyi-st" id="yiyi-87">服务器项目</span></h2><p><span class="yiyi-st" id="yiyi-88"><a class="reference internal" href="#xmlrpc.client.ServerProxy" title="xmlrpc.client.ServerProxy"><code class="xref py py-class docutils literal"><span class="pre">ServerProxy</span></code></a>实例具有与XML-RPC服务器接受的每个远程过程调用相对应的方法。</span><span class="yiyi-st" id="yiyi-89">调用方法执行RPC通过名称和参数签名例如</span><span class="yiyi-st" id="yiyi-90">相同的方法名称可以重载多个参数签名)。</span><span class="yiyi-st" id="yiyi-91">RPC通过返回一个值完成这一过程该值可以是符合类型的返回数据或者是指示错误的<a class="reference internal" href="#xmlrpc.client.Fault" title="xmlrpc.client.Fault"><code class="xref py py-class docutils literal"><span class="pre">Fault</span></code></a><a class="reference internal" href="#xmlrpc.client.ProtocolError" title="xmlrpc.client.ProtocolError"><code class="xref py py-class docutils literal"><span class="pre">ProtocolError</span></code></a>对象。</span></p><p><span class="yiyi-st" id="yiyi-92">支持XML自省API的服务器支持在保留的<code class="xref py py-attr docutils literal"><span class="pre">系统</span></code>属性下分组的一些常用方法:</span></p><dl class="method"><dt id="xmlrpc.client.ServerProxy.system.listMethods"><span class="yiyi-st" id="yiyi-93"> <code class="descclassname">ServerProxy.system.</code><code class="descname">listMethods</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-94">此方法返回一个字符串列表一个每个XML-RPC服务器都支持的非系统方法。</span></p></dd></dl><dl class="method"><dt id="xmlrpc.client.ServerProxy.system.methodSignature"><span class="yiyi-st" id="yiyi-95"> <code class="descclassname">ServerProxy.system.</code><code class="descname">methodSignature</code><span class="sig-paren">(</span><em>name</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-96">此方法接受一个参数即XML-RPC服务器实现的方法的名称。</span><span class="yiyi-st" id="yiyi-97">它返回此方法的可能的签名所组成的数组。</span><span class="yiyi-st" id="yiyi-98">签名是一个类型数组。</span><span class="yiyi-st" id="yiyi-99">第一种类型是方法的返回类型,其余的都是参数。</span></p><p><span class="yiyi-st" id="yiyi-100">因为多个签名(即</span><span class="yiyi-st" id="yiyi-101">重载)是允许的,所以此方法返回签名列表而不是单例。</span></p><p><span class="yiyi-st" id="yiyi-102">签名本身仅限于方法预期的顶级参数。</span><span class="yiyi-st" id="yiyi-103">对于实例如果一个方法期望一个结构体数组作为参数并返回一个字符串那么它的签名只是“stringarray”。</span><span class="yiyi-st" id="yiyi-104">如果它期望三个整数并返回一个字符串它的签名是“stringintintint”。</span></p><p><span class="yiyi-st" id="yiyi-105">如果没有为方法定义签名,则返回非数组值。</span><span class="yiyi-st" id="yiyi-106">在Python中这意味着返回值的类型将不是list。</span></p></dd></dl><dl class="method"><dt id="xmlrpc.client.ServerProxy.system.methodHelp"><span class="yiyi-st" id="yiyi-107"> <code class="descclassname">ServerProxy.system.</code><code class="descname">methodHelp</code><span class="sig-paren">(</span><em>name</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-108">此方法接受一个参数即XML-RPC服务器实现的方法的名称。</span><span class="yiyi-st" id="yiyi-109">它返回一个描述该方法的使用的文档字符串。</span><span class="yiyi-st" id="yiyi-110">如果没有发现这样的字符串可用,则返回一个空字符串。</span><span class="yiyi-st" id="yiyi-111">文档字符串可能包含HTML标记。</span></p></dd></dl><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-112"><span class="versionmodified">在3.5版本中更改:</span> <a class="reference internal" href="#xmlrpc.client.ServerProxy" title="xmlrpc.client.ServerProxy"><code class="xref py py-class docutils literal"><span class="pre">ServerProxy</span></code></a>的实例支持关闭底层传输的<a class="reference internal" href="../glossary.html#term-context-manager"><span class="xref std std-term">context manager</span></a>协议。</span></p></div><p><span class="yiyi-st" id="yiyi-113">下面是一个工作示例</span><span class="yiyi-st" id="yiyi-114">,代码如下:</span></p><pre><code class="language-python"><span></span><span class="kn">from</span> <span class="nn">xmlrpc.server</span> <span class="k">import</span> <span class="n">SimpleXMLRPCServer</span>
<span class="k">def</span> <span class="nf">is_even</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
<span class="k">return</span> <span class="n">n</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span>
<span class="n">server</span> <span class="o">=</span> <span class="n">SimpleXMLRPCServer</span><span class="p">((</span><span class="s2">"localhost"</span><span class="p">,</span> <span class="mi">8000</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Listening on port 8000..."</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">register_function</span><span class="p">(</span><span class="n">is_even</span><span class="p">,</span> <span class="s2">"is_even"</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>
</code></pre><p><span class="yiyi-st" id="yiyi-115">上述服务器所对应的客户端的代码如下:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">xmlrpc.client</span>
<span class="k">with</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">ServerProxy</span><span class="p">(</span><span class="s2">"http://localhost:8000/"</span><span class="p">)</span> <span class="k">as</span> <span class="n">proxy</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"3 is even: </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">proxy</span><span class="o">.</span><span class="n">is_even</span><span class="p">(</span><span class="mi">3</span><span class="p">)))</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"100 is even: </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">proxy</span><span class="o">.</span><span class="n">is_even</span><span class="p">(</span><span class="mi">100</span><span class="p">)))</span>
</code></pre></div><div class="section" id="datetime-objects"><h2><span class="yiyi-st" id="yiyi-116">21.26.2. </span><span class="yiyi-st" id="yiyi-117">DateTime Objects</span></h2><dl class="class"><dt id="xmlrpc.client.DateTime"><span class="yiyi-st" id="yiyi-118"> <em class="property">class </em><code class="descclassname">xmlrpc.client.</code><code class="descname">DateTime</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-119">此类可以从时代开始以秒为单位初始化时间元组ISO 8601时间/日期字符串或<a class="reference internal" href="datetime.html#datetime.datetime" title="datetime.datetime"><code class="xref py py-class docutils literal"><span class="pre">datetime.datetime</span></code></a>实例。</span><span class="yiyi-st" id="yiyi-120">它有以下方法,主要支持由编组/取消编组代码内部使用:</span></p><dl class="method"><dt id="xmlrpc.client.DateTime.decode"><span class="yiyi-st" id="yiyi-121"> <code class="descname">decode</code><span class="sig-paren">(</span><em>string</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-122">接受一个字符串作为实例的新时间值。</span></p></dd></dl><dl class="method"><dt id="xmlrpc.client.DateTime.encode"><span class="yiyi-st" id="yiyi-123"> <code class="descname">encode</code><span class="sig-paren">(</span><em>out</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-124">将此<a class="reference internal" href="#xmlrpc.client.DateTime" title="xmlrpc.client.DateTime"><code class="xref py py-class docutils literal"><span class="pre">DateTime</span></code></a>项的XML-RPC编码写入<em>输出</em>流对象。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-125">它还通过丰富的比较和<a class="reference internal" href="../reference/datamodel.html#object.__repr__" title="object.__repr__"><code class="xref py py-meth docutils literal"><span class="pre">__repr__()</span></code></a>方法支持某些Python的内建运算符。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-126">下面是一个工作示例。</span><span class="yiyi-st" id="yiyi-127">服务器代码:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">datetime</span>
<span class="kn">from</span> <span class="nn">xmlrpc.server</span> <span class="k">import</span> <span class="n">SimpleXMLRPCServer</span>
<span class="kn">import</span> <span class="nn">xmlrpc.client</span>
<span class="k">def</span> <span class="nf">today</span><span class="p">():</span>
<span class="n">today</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">today</span><span class="p">()</span>
<span class="k">return</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">DateTime</span><span class="p">(</span><span class="n">today</span><span class="p">)</span>
<span class="n">server</span> <span class="o">=</span> <span class="n">SimpleXMLRPCServer</span><span class="p">((</span><span class="s2">"localhost"</span><span class="p">,</span> <span class="mi">8000</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Listening on port 8000..."</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">register_function</span><span class="p">(</span><span class="n">today</span><span class="p">,</span> <span class="s2">"today"</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>
</code></pre><p><span class="yiyi-st" id="yiyi-128">上述服务器的客户端代码:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">xmlrpc.client</span>
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="n">proxy</span> <span class="o">=</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">ServerProxy</span><span class="p">(</span><span class="s2">"http://localhost:8000/"</span><span class="p">)</span>
<span class="n">today</span> <span class="o">=</span> <span class="n">proxy</span><span class="o">.</span><span class="n">today</span><span class="p">()</span>
<span class="c1"># convert the ISO8601 string to a datetime object</span>
<span class="n">converted</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="n">today</span><span class="o">.</span><span class="n">value</span><span class="p">,</span> <span class="s2">"%Y%m</span><span class="si">%d</span><span class="s2">T%H:%M:%S"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Today: </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">converted</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">"</span><span class="si">%d</span><span class="s2">.%m.%Y, %H:%M"</span><span class="p">))</span>
</code></pre></div><div class="section" id="binary-objects"><h2><span class="yiyi-st" id="yiyi-129">21.26.3. </span><span class="yiyi-st" id="yiyi-130">Binary Objects</span></h2><dl class="class"><dt id="xmlrpc.client.Binary"><span class="yiyi-st" id="yiyi-131"> <em class="property">class </em><code class="descclassname">xmlrpc.client.</code><code class="descname">Binary</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-132">该类可以从字节数据其可以包括NUL初始化。</span><span class="yiyi-st" id="yiyi-133"><a class="reference internal" href="#xmlrpc.client.Binary" title="xmlrpc.client.Binary"><code class="xref py py-class docutils literal"><span class="pre">Binary</span></code></a>对象的内容的主访问由属性提供:</span></p><dl class="attribute"><dt id="xmlrpc.client.Binary.data"><span class="yiyi-st" id="yiyi-134"> <code class="descname">data</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-135"><a class="reference internal" href="#xmlrpc.client.Binary" title="xmlrpc.client.Binary"><code class="xref py py-class docutils literal"><span class="pre">Binary</span></code></a>实例封装的二进制数据。</span><span class="yiyi-st" id="yiyi-136">数据作为<a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a>对象提供。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-137"><a class="reference internal" href="#xmlrpc.client.Binary" title="xmlrpc.client.Binary"><code class="xref py py-class docutils literal"><span class="pre">Binary</span></code></a>对象具有以下方法,主要由编组/取消编组代码内部使用:</span></p><dl class="method"><dt id="xmlrpc.client.Binary.decode"><span class="yiyi-st" id="yiyi-138"> <code class="descname">decode</code><span class="sig-paren">(</span><em>bytes</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-139">接受base64 <a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a>对象,并将其解码为实例的新数据。</span></p></dd></dl><dl class="method"><dt id="xmlrpc.client.Binary.encode"><span class="yiyi-st" id="yiyi-140"> <code class="descname">encode</code><span class="sig-paren">(</span><em>out</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-141">将此二进制项的XML-RPC base 64编码写入<em>out</em>流对象。</span></p><p><span class="yiyi-st" id="yiyi-142">编码数据将根据<a class="reference external" href="https://tools.ietf.org/html/rfc2045#section-6.8">RFC 2045第6.8节</a>每76个字符有换行符这是写入XML-RPC规范时事实上的标准base64规范。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-143">它还通过<a class="reference internal" href="../reference/datamodel.html#object.__eq__" title="object.__eq__"><code class="xref py py-meth docutils literal"><span class="pre">__eq__()</span></code></a><a class="reference internal" href="../reference/datamodel.html#object.__ne__" title="object.__ne__"><code class="xref py py-meth docutils literal"><span class="pre">__ne__()</span></code></a>方法支持某些Python的内建运算符。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-144">二进制对象的用法示例。</span><span class="yiyi-st" id="yiyi-145">我们将通过XMLRPC传输图像</span></p><pre><code class="language-python"><span></span><span class="kn">from</span> <span class="nn">xmlrpc.server</span> <span class="k">import</span> <span class="n">SimpleXMLRPCServer</span>
<span class="kn">import</span> <span class="nn">xmlrpc.client</span>
<span class="k">def</span> <span class="nf">python_logo</span><span class="p">():</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"python_logo.jpg"</span><span class="p">,</span> <span class="s2">"rb"</span><span class="p">)</span> <span class="k">as</span> <span class="n">handle</span><span class="p">:</span>
<span class="k">return</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">Binary</span><span class="p">(</span><span class="n">handle</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="n">server</span> <span class="o">=</span> <span class="n">SimpleXMLRPCServer</span><span class="p">((</span><span class="s2">"localhost"</span><span class="p">,</span> <span class="mi">8000</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Listening on port 8000..."</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">register_function</span><span class="p">(</span><span class="n">python_logo</span><span class="p">,</span> <span class="s1">'python_logo'</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>
</code></pre><p><span class="yiyi-st" id="yiyi-146">客户端获取映像并将其保存到文件中:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">xmlrpc.client</span>
<span class="n">proxy</span> <span class="o">=</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">ServerProxy</span><span class="p">(</span><span class="s2">"http://localhost:8000/"</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"fetched_python_logo.jpg"</span><span class="p">,</span> <span class="s2">"wb"</span><span class="p">)</span> <span class="k">as</span> <span class="n">handle</span><span class="p">:</span>
<span class="n">handle</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">proxy</span><span class="o">.</span><span class="n">python_logo</span><span class="p">()</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
</code></pre></div><div class="section" id="fault-objects"><h2><span class="yiyi-st" id="yiyi-147">21.26.4. </span><span class="yiyi-st" id="yiyi-148">Fault Objects</span></h2><dl class="class"><dt id="xmlrpc.client.Fault"><span class="yiyi-st" id="yiyi-149"> <em class="property">class </em><code class="descclassname">xmlrpc.client.</code><code class="descname">Fault</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-150"><a class="reference internal" href="#xmlrpc.client.Fault" title="xmlrpc.client.Fault"><code class="xref py py-class docutils literal"><span class="pre">Fault</span></code></a>对象封装了XML-RPC故障标记的内容。</span><span class="yiyi-st" id="yiyi-151">故障对象具有以下属性:</span></p><dl class="attribute"><dt id="xmlrpc.client.Fault.faultCode"><span class="yiyi-st" id="yiyi-152"> <code class="descname">faultCode</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-153">指示故障类型的字符串。</span></p></dd></dl><dl class="attribute"><dt id="xmlrpc.client.Fault.faultString"><span class="yiyi-st" id="yiyi-154"> <code class="descname">faultString</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-155">包含与故障相关联的诊断消息的字符串。</span></p></dd></dl></dd></dl><p><span class="yiyi-st" id="yiyi-156">在下面的示例中,我们将通过返回一个复杂类型对象来故意造成<a class="reference internal" href="#xmlrpc.client.Fault" title="xmlrpc.client.Fault"><code class="xref py py-exc docutils literal"><span class="pre">Fault</span></code></a></span><span class="yiyi-st" id="yiyi-157">服务器代码:</span></p><pre><code class="language-python"><span></span><span class="kn">from</span> <span class="nn">xmlrpc.server</span> <span class="k">import</span> <span class="n">SimpleXMLRPCServer</span>
<span class="c1"># A marshalling error is going to occur because we're returning a</span>
<span class="c1"># complex number</span>
<span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="k">return</span> <span class="n">x</span><span class="o">+</span><span class="n">y</span><span class="o">+</span><span class="mi">0</span><span class="n">j</span>
<span class="n">server</span> <span class="o">=</span> <span class="n">SimpleXMLRPCServer</span><span class="p">((</span><span class="s2">"localhost"</span><span class="p">,</span> <span class="mi">8000</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Listening on port 8000..."</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">register_function</span><span class="p">(</span><span class="n">add</span><span class="p">,</span> <span class="s1">'add'</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>
</code></pre><p><span class="yiyi-st" id="yiyi-158">上述服务器的客户端代码:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">xmlrpc.client</span>
<span class="n">proxy</span> <span class="o">=</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">ServerProxy</span><span class="p">(</span><span class="s2">"http://localhost:8000/"</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">proxy</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
<span class="k">except</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">Fault</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"A fault occurred"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Fault code: </span><span class="si">%d</span><span class="s2">"</span> <span class="o">%</span> <span class="n">err</span><span class="o">.</span><span class="n">faultCode</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Fault string: </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">err</span><span class="o">.</span><span class="n">faultString</span><span class="p">)</span>
</code></pre></div><div class="section" id="protocolerror-objects"><h2><span class="yiyi-st" id="yiyi-159">21.26.5. </span><span class="yiyi-st" id="yiyi-160">ProtocolError Objects</span></h2><dl class="class"><dt id="xmlrpc.client.ProtocolError"><span class="yiyi-st" id="yiyi-161"> <em class="property">class </em><code class="descclassname">xmlrpc.client.</code><code class="descname">ProtocolError</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-162"><a class="reference internal" href="#xmlrpc.client.ProtocolError" title="xmlrpc.client.ProtocolError"><code class="xref py py-class docutils literal"><span class="pre">ProtocolError</span></code></a>对象描述底层传输层中的协议错误例如如果由URI命名的服务器不存在则404“未找到”错误</span><span class="yiyi-st" id="yiyi-163">它具有以下属性:</span></p><dl class="attribute"><dt id="xmlrpc.client.ProtocolError.url"><span class="yiyi-st" id="yiyi-164"> <code class="descname">url</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-165">触发错误的URI或URL。</span></p></dd></dl><dl class="attribute"><dt id="xmlrpc.client.ProtocolError.errcode"><span class="yiyi-st" id="yiyi-166"> <code class="descname">errcode</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-167">错误代码。</span></p></dd></dl><dl class="attribute"><dt id="xmlrpc.client.ProtocolError.errmsg"><span class="yiyi-st" id="yiyi-168"> <code class="descname">errmsg</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-169">错误消息或诊断字符串。</span></p></dd></dl><dl class="attribute"><dt id="xmlrpc.client.ProtocolError.headers"><span class="yiyi-st" id="yiyi-170"> <code class="descname">headers</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-171">包含触发错误的HTTP / HTTPS请求标头的字典。</span></p></dd></dl></dd></dl><p><span class="yiyi-st" id="yiyi-172">在下面的示例中我们将通过提供无效的URI来故意导致<a class="reference internal" href="#xmlrpc.client.ProtocolError" title="xmlrpc.client.ProtocolError"><code class="xref py py-exc docutils literal"><span class="pre">ProtocolError</span></code></a></span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">xmlrpc.client</span>
<span class="c1"># create a ServerProxy with a URI that doesn't respond to XMLRPC requests</span>
<span class="n">proxy</span> <span class="o">=</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">ServerProxy</span><span class="p">(</span><span class="s2">"http://google.com/"</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">proxy</span><span class="o">.</span><span class="n">some_method</span><span class="p">()</span>
<span class="k">except</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">ProtocolError</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"A protocol error occurred"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"URL: </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">err</span><span class="o">.</span><span class="n">url</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"HTTP/HTTPS headers: </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">err</span><span class="o">.</span><span class="n">headers</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Error code: </span><span class="si">%d</span><span class="s2">"</span> <span class="o">%</span> <span class="n">err</span><span class="o">.</span><span class="n">errcode</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Error message: </span><span class="si">%s</span><span class="s2">"</span> <span class="o">%</span> <span class="n">err</span><span class="o">.</span><span class="n">errmsg</span><span class="p">)</span>
</code></pre></div><div class="section" id="multicall-objects"><h2><span class="yiyi-st" id="yiyi-173">21.26.6. </span><span class="yiyi-st" id="yiyi-174">多对象对象</span></h2><p><span class="yiyi-st" id="yiyi-175"><a class="reference internal" href="#xmlrpc.client.MultiCall" title="xmlrpc.client.MultiCall"><code class="xref py py-class docutils literal"><span class="pre">MultiCall</span></code></a> 对象提供了一种将对远程服务器的多个调用封装到单个请求中的方法 <a class="footnote-reference" href="#id6" id="id5">[1]</a>.</span></p><dl class="class"><dt id="xmlrpc.client.MultiCall"><span class="yiyi-st" id="yiyi-176"> <em class="property">class </em><code class="descclassname">xmlrpc.client.</code><code class="descname">MultiCall</code><span class="sig-paren">(</span><em>server</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-177">创建一个用于boxcar方法调用的对象。</span><span class="yiyi-st" id="yiyi-178"><em>服务器</em> 是最终的调用目标</span><span class="yiyi-st" id="yiyi-179">可以对结果对象进行调用,但是它们将立即返回 <code class="docutils literal"><span class="pre">None</span></code>,并且仅将调用名称和参数存储在 <a class="reference internal" href="#xmlrpc.client.MultiCall" title="xmlrpc.client.MultiCall"><code class="xref py py-class docutils literal"><span class="pre">MultiCall</span></code></a> 对象中。</span><span class="yiyi-st" id="yiyi-180">调用对象本身会导致所有存储的调用作为单个<code class="docutils literal"><span class="pre">system.multicall</span></code>请求传输。</span><span class="yiyi-st" id="yiyi-181">这个调用的结果是一个<a class="reference internal" href="../glossary.html#term-generator"><span class="xref std std-term">generator迭代器</span></a>; 迭代该生成器产生单独的结果。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-182">下面是一个可用的例子</span><span class="yiyi-st" id="yiyi-183">服务器代码:</span></p><pre><code class="language-python"><span></span><span class="kn">from</span> <span class="nn">xmlrpc.server</span> <span class="k">import</span> <span class="n">SimpleXMLRPCServer</span>
<span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="k">return</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span>
<span class="k">def</span> <span class="nf">subtract</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="k">return</span> <span class="n">x</span> <span class="o">-</span> <span class="n">y</span>
<span class="k">def</span> <span class="nf">multiply</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="k">return</span> <span class="n">x</span> <span class="o">*</span> <span class="n">y</span>
<span class="k">def</span> <span class="nf">divide</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="k">return</span> <span class="n">x</span> <span class="o">//</span> <span class="n">y</span>
<span class="c1"># A simple server with simple arithmetic functions</span>
<span class="n">server</span> <span class="o">=</span> <span class="n">SimpleXMLRPCServer</span><span class="p">((</span><span class="s2">"localhost"</span><span class="p">,</span> <span class="mi">8000</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Listening on port 8000..."</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">register_multicall_functions</span><span class="p">()</span>
<span class="n">server</span><span class="o">.</span><span class="n">register_function</span><span class="p">(</span><span class="n">add</span><span class="p">,</span> <span class="s1">'add'</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">register_function</span><span class="p">(</span><span class="n">subtract</span><span class="p">,</span> <span class="s1">'subtract'</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">register_function</span><span class="p">(</span><span class="n">multiply</span><span class="p">,</span> <span class="s1">'multiply'</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">register_function</span><span class="p">(</span><span class="n">divide</span><span class="p">,</span> <span class="s1">'divide'</span><span class="p">)</span>
<span class="n">server</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>
</code></pre><p><span class="yiyi-st" id="yiyi-184">上述服务器所对应的客户端代码如下:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">xmlrpc.client</span>
<span class="n">proxy</span> <span class="o">=</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">ServerProxy</span><span class="p">(</span><span class="s2">"http://localhost:8000/"</span><span class="p">)</span>
<span class="n">multicall</span> <span class="o">=</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">MultiCall</span><span class="p">(</span><span class="n">proxy</span><span class="p">)</span>
<span class="n">multicall</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="mi">7</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">multicall</span><span class="o">.</span><span class="n">subtract</span><span class="p">(</span><span class="mi">7</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">multicall</span><span class="o">.</span><span class="n">multiply</span><span class="p">(</span><span class="mi">7</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">multicall</span><span class="o">.</span><span class="n">divide</span><span class="p">(</span><span class="mi">7</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">multicall</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"7+3=</span><span class="si">%d</span><span class="s2">, 7-3=</span><span class="si">%d</span><span class="s2">, 7*3=</span><span class="si">%d</span><span class="s2">, 7//3=</span><span class="si">%d</span><span class="s2">"</span> <span class="o">%</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">result</span><span class="p">))</span>
</code></pre></div><div class="section" id="convenience-functions"><h2><span class="yiyi-st" id="yiyi-185">21.26.7. </span><span class="yiyi-st" id="yiyi-186">便利功能</span></h2><dl class="function"><dt id="xmlrpc.client.dumps"><span class="yiyi-st" id="yiyi-187"> <code class="descclassname">xmlrpc.client.</code><code class="descname">dumps</code><span class="sig-paren">(</span><em>params</em>, <em>methodname=None</em>, <em>methodresponse=None</em>, <em>encoding=None</em>, <em>allow_none=False</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-188"><em>params</em>转换为XML-RPC请求。</span><span class="yiyi-st" id="yiyi-189">或者如果<em>方法响应</em>为真,则返回响应。</span><span class="yiyi-st" id="yiyi-190"><em>params</em>可以是参数的一个元组,也可以是<a class="reference internal" href="#xmlrpc.client.Fault" title="xmlrpc.client.Fault"><code class="xref py py-exc docutils literal"><span class="pre">Fault</span></code></a>异常类的实例。</span><span class="yiyi-st" id="yiyi-191">如果<em>methodresponse</em>为true则只能返回一个值这意味着<em>params</em>必须为长度1. <em>encoding</em>编码用于生成的XML默认值为UTF-8。</span><span class="yiyi-st" id="yiyi-192">Python的<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>值不能在标准XML-RPC中使用以允许通过扩展使用它<em>allow_none</em>提供真实值。</span></p></dd></dl><dl class="function"><dt id="xmlrpc.client.loads"><span class="yiyi-st" id="yiyi-193"> <code class="descclassname">xmlrpc.client.</code><code class="descname">loads</code><span class="sig-paren">(</span><em>data</em>, <em>use_datetime=False</em>, <em>use_builtin_types=False</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-194">将XML-RPC请求或响应转换为Python对象<code class="docutils literal"><span class="pre">params</span> <span class="pre">methodname</span></code></span><span class="yiyi-st" id="yiyi-195"><em>params</em>是参数的元组; <em>methodname</em>是字符串,或<code class="docutils literal"><span class="pre">None</span></code>如果数据包中没有方法名称。</span><span class="yiyi-st" id="yiyi-196">如果XML-RPC数据包表示故障条件则此函数将引发<a class="reference internal" href="#xmlrpc.client.Fault" title="xmlrpc.client.Fault"><code class="xref py py-exc docutils literal"><span class="pre">Fault</span></code></a>异常。</span><span class="yiyi-st" id="yiyi-197"><em>use_builtin_types</em>标志可用于使日期/时间值显示为<a class="reference internal" href="datetime.html#datetime.datetime" title="datetime.datetime"><code class="xref py py-class docutils literal"><span class="pre">datetime.datetime</span></code></a>对象,二进制数据显示为<a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a>对象默认情况下此标志为false。</span></p><p><span class="yiyi-st" id="yiyi-198">过时的<em>use_datetime</em>标志与<em>use_builtin_types</em>类似,但它仅适用于日期/时间值。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-199"><span class="versionmodified">在版本3.3中已更改:</span>添加了<em>use_builtin_types</em>标志。</span></p></div></dd></dl></div><div class="section" id="example-of-client-usage"><h2><span class="yiyi-st" id="yiyi-200">21.26.8. </span><span class="yiyi-st" id="yiyi-201">Example of Client Usage</span></h2><pre><code class="language-python"><span></span><span class="c1"># simple test program (from the XML-RPC specification)</span>
<span class="kn">from</span> <span class="nn">xmlrpc.client</span> <span class="k">import</span> <span class="n">ServerProxy</span><span class="p">,</span> <span class="n">Error</span>
<span class="c1"># server = ServerProxy("http://localhost:8000") # local server</span>
<span class="k">with</span> <span class="n">ServerProxy</span><span class="p">(</span><span class="s2">"http://betty.userland.com"</span><span class="p">)</span> <span class="k">as</span> <span class="n">proxy</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">proxy</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">proxy</span><span class="o">.</span><span class="n">examples</span><span class="o">.</span><span class="n">getStateName</span><span class="p">(</span><span class="mi">41</span><span class="p">))</span>
<span class="k">except</span> <span class="n">Error</span> <span class="k">as</span> <span class="n">v</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"ERROR"</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span>
</code></pre><p><span class="yiyi-st" id="yiyi-202">要通过HTTP代理访问XML-RPC服务器您需要定义自定义传输。</span><span class="yiyi-st" id="yiyi-203">以下示例显示如何:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">xmlrpc.client</span><span class="o">,</span> <span class="nn">http.client</span>
<span class="k">class</span> <span class="nc">ProxiedTransport</span><span class="p">(</span><span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">Transport</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">set_proxy</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">proxy</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">proxy</span> <span class="o">=</span> <span class="n">proxy</span>
<span class="k">def</span> <span class="nf">make_connection</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">realhost</span> <span class="o">=</span> <span class="n">host</span>
<span class="n">h</span> <span class="o">=</span> <span class="n">http</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">HTTPConnection</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">proxy</span><span class="p">)</span>
<span class="k">return</span> <span class="n">h</span>
<span class="k">def</span> <span class="nf">send_request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">connection</span><span class="p">,</span> <span class="n">handler</span><span class="p">,</span> <span class="n">request_body</span><span class="p">,</span> <span class="n">debug</span><span class="p">):</span>
<span class="n">connection</span><span class="o">.</span><span class="n">putrequest</span><span class="p">(</span><span class="s2">"POST"</span><span class="p">,</span> <span class="s1">'http://</span><span class="si">%s%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">realhost</span><span class="p">,</span> <span class="n">handler</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">send_host</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">connection</span><span class="p">,</span> <span class="n">host</span><span class="p">):</span>
<span class="n">connection</span><span class="o">.</span><span class="n">putheader</span><span class="p">(</span><span class="s1">'Host'</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">realhost</span><span class="p">)</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">ProxiedTransport</span><span class="p">()</span>
<span class="n">p</span><span class="o">.</span><span class="n">set_proxy</span><span class="p">(</span><span class="s1">'proxy-server:8080'</span><span class="p">)</span>
<span class="n">server</span> <span class="o">=</span> <span class="n">xmlrpc</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">ServerProxy</span><span class="p">(</span><span class="s1">'http://time.xmlrpc.com/RPC2'</span><span class="p">,</span> <span class="n">transport</span><span class="o">=</span><span class="n">p</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">server</span><span class="o">.</span><span class="n">currentTime</span><span class="o">.</span><span class="n">getCurrentTime</span><span class="p">())</span>
</code></pre></div><div class="section" id="example-of-client-and-server-usage"><h2><span class="yiyi-st" id="yiyi-204">21.26.9. </span><span class="yiyi-st" id="yiyi-205">Example of Client and Server Usage</span></h2><p><span class="yiyi-st" id="yiyi-206">请参见<a class="reference internal" href="xmlrpc.server.html#simplexmlrpcserver-example"><span>SimpleXMLRPCServer Example</span></a></span></p><p class="rubric"><span class="yiyi-st" id="yiyi-207">脚注</span></p><table class="docutils footnote" frame="void" id="id6" rules="none"><tbody valign="top"><tr><td class="label"><span class="yiyi-st" id="yiyi-208"><a class="fn-backref" href="#id5">[1]</a></span></td><td><span class="yiyi-st" id="yiyi-209">这种方法已经在<a class="reference external" href="https://web.archive.org/web/20060624230303/http://www.xmlrpc.com/discuss/msgReader$1208?mode=topic">关于xmlrpc.com</a>的讨论中首次提出。</span></td></tr></tbody></table></div></div></div>