Changeset 913
- Timestamp:
- Fri Mar 17 21:47:48 2006
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
-
zh-translations/branches/diveintopython-zh-5.4/zh-cn/xml/apihelper.xml
r860 r913 3 3 <?dbhtml filename="power_of_introspection/index.html"?> 4 4 <title>自省的威力</title> 5 <titleabbrev id="apihelper.numberonly"> Chapter 4</titleabbrev>5 <titleabbrev id="apihelper.numberonly">第 4 章</titleabbrev> 5 5 <abstract> 6 6 <title/> … … 122 122 <section> 123 123 <title>&type; 函数</title> 124 <para>&type; 函数返回任意对象的数据 型别。在<filename class="headerfile">types</filename>模块中列出了可能的型别。这对于帮助者函数处理不同种型别的数据非常有用。</para>124 <para>&type; 函数返回任意对象的数据类型。在<filename class="headerfile">types</filename>模块中列出了可能的数据类型。这对于处理多种数据类型的帮助者函数非常有用。</para> 124 124 <example id="apihelper.type.intro"> 125 125 <title>&type; 介绍</title> … … 138 138 <calloutlist> 139 139 <callout arearefs="apihelper.builtin.1.1"> 140 <para>&type; 可以接收任何东西作为参数 -- 我的意思是任何东西 -- 并返回它的数据 型别。整型、字符串、列表、字典、元组、函数、类、模块、甚至类型对象都可以作为参数被type函数接受。</para>140 <para>&type; 可以接收任何东西作为参数 -- 我的意思是任何东西 -- 并返回它的数据类型。整型、字符串、列表、字典、元组、函数、类、模块、甚至类型对象都可以作为参数被type函数接受。</para> 140 140 </callout> 141 141 <callout arearefs="apihelper.builtin.1.2"> 142 <para>&type; 可以接收变量作为参数,并返回它的数据 型别。</para>142 <para>&type; 可以接收变量作为参数,并返回它的数据类型。</para> 142 142 </callout> 143 143 <callout arearefs="apihelper.builtin.1.3"> … … 147 147 </callout> 148 148 <callout arearefs="apihelper.builtin.1.4"> 149 <para>你可以使用<filename class="headerfile">types</filename>模块中的常量来进行对象 型别的比较。这就是&info; 函数所做的,很快你就会看到。</para>149 <para>你可以使用<filename class="headerfile">types</filename>模块中的常量来进行对象类型的比较。这就是&info; 函数所做的,很快你就会看到。</para> 149 149 </callout> 150 150 </calloutlist> … … 154 154 <section> 155 155 <title>&str; 函数</title> 156 <para>&str; 将数据强制转型为字符串。每种数据 型别都可以强制转型为字符串。</para>156 <para>&str; 将数据强制转型为字符串。每种数据类型都可以强制转型为字符串。</para> 156 156 <example id="apihelper.str.intro"> 157 157 <title>&str; 介绍</title> … … 172 172 <calloutlist> 173 173 <callout arearefs="apihelper.builtin.2.1"> 174 <para>对于简单的数据 型别比如整型,你可以预料到 &str; 的正常工作,因为几乎每种语言都有一个将整型转化为字符串的函数。</para>174 <para>对于简单的数据类型比如整型,你可以预料到 &str; 的正常工作,因为几乎每种语言都有一个将整型转化为字符串的函数。</para> 174 174 </callout> 175 175 <callout arearefs="apihelper.builtin.2.2"> 176 <para>然而 &str; 可以作用于任何 型别的任何对象。这里它作用于一个零碎构建的列表。</para>176 <para>然而 &str; 可以作用于任何数据类型的任何对象。这里它作用于一个零碎构建的列表。</para> 176 176 </callout> 177 177 <callout arearefs="apihelper.builtin.2.3"> … … 272 272 <note id="tip.manuals"> 273 273 <title>&python; 是自文档化的</title> 274 <para>&python; 提供了很多出色的参考手册,你应该好好的精读一下所有 &python; 提供的必备 274 <para>&python; 提供了很多出色的参考手册,你应该好好的精读一下所有 &python; 提供的必备模块。对于其它大部分语言,你会发现自己要常常回头参考手册或者man页来提醒自己如何使用这些模块,但是&python;不同于此,它很大程度上是自文档化的。</para> 274 274 </note> 275 275 <itemizedlist role="furtherreading"> … … 322 322 <section> 323 323 <title>用于模块的 &getattr;</title> 324 <para>&getattr; 不仅仅适用于内置数据 型别,也可作用于模块。</para>324 <para>&getattr; 不仅仅适用于内置数据类型,也可作用于模块。</para> 324 324 <example id="apihelper.getattr.example"> 325 325 <title>&apihelper_filename; 中的&getattr; 函数</title> … … 398 398 <calloutlist> 399 399 <callout arearefs="apihelper.getattr.4.1"> 400 <para>这个函数调用确保可以工作,因为你在调用&getattr; 时添加了第三个参数。第三个参数是一个缺省返回值,如果第二个参数指定的属性或者方法没 有找到将返回这个缺省返回值。</para>400 <para>这个函数调用确保可以工作,因为你在调用&getattr; 时添加了第三个参数。第三个参数是一个缺省返回值,如果第二个参数指定的属性或者方法没能找到,则将返回这个缺省返回值。</para> 400 400 </callout> 401 401 </calloutlist> … … 410 410 <abstract> 411 411 <title/> 412 <para>如你所知,&python; 具有通过列表 解析(<xref linkend="odbchelper.map"/>)将列表映射到其它列表的强大能力。这种能力同过滤机制结合使用,使列表中的有些元素可以被映射而有些则一概跳过。</para>412 <para>如你所知,&python; 具有通过列表遍历(<xref linkend="odbchelper.map"/>)将列表映射到其它列表的强大能力。这种能力同过滤机制结合使用,使列表中的有些元素被映射的同时跳过另外一些元素。</para> 412 412 </abstract> 413 413 <informalexample> … … 430 430 <calloutlist> 431 431 <callout arearefs="apihelper.filter.1.1"> 432 <para>这里的映射表达式很简单(只是返回每个元素的值),所以请把注意力集中到过滤器表达式上。由于&python; 会遍历整个列表,它将对每个元素执行过滤器表达式。如果过滤器表达式演算值为真,该元素就会被映射,同时映射表达式的结果将包含在返回的列表中。这里,你过滤掉了所有单字符的字符串,留下了一个 都是长字符串的列表。</para>432 <para>这里的映射表达式很简单(只是返回每个元素的值),所以请把注意力集中到过滤器表达式上。由于&python; 会遍历整个列表,它将对每个元素执行过滤器表达式。如果过滤器表达式演算值为真,该元素就会被映射,同时映射表达式的结果将包含在返回的列表中。这里,你过滤掉了所有单字符的字符串,留下了一个由长字符串构成的列表。</para> 432 432 </callout> 433 433 <callout arearefs="apihelper.filter.1.2"> … … 436 436 </callout> 437 437 <callout arearefs="apihelper.filter.1.3"> 438 <para>&count; 是一个列表方法,返回某个值在列表中出现的次数。你可以认为这个过滤器将从列表中剔除重复元素,返回一个只包含了在原始列表中有着唯一值拷贝的列表。但 是不是这样的,因为在原始列表中出现两次的值(在本例中,<literal>b</literal> 和 <literal>d</literal>)被完全剔除了。存在从一个列表排除重复值的方法,但过滤并非解决之道。</para>438 <para>&count; 是一个列表方法,返回某个值在列表中出现的次数。你可以认为这个过滤器将从列表中剔除重复元素,返回一个只包含了在原始列表中有着唯一值拷贝的列表。但并非如此,因为在原始列表中出现两次的值(在本例中,<literal>b</literal> 和 <literal>d</literal>)被完全剔除了。从一个列表中排除重复值有多种方法,但过滤并不是其中的一种。</para> 438 438 </callout> 439 439 </calloutlist> … … 448 448 <para>这行看上去挺复杂的,确实也很复杂,但是基本结构都还是一样的。整个过滤表达式返回一个列表,并赋值给 <varname>methodList</varname> 变量。表达式的前半部分是列表映射部分。映射表达式是一个和遍历元素相同的表达式,因此它返回每个元素的值。<literal>&dir;(<varname>object</varname>)</literal> 返回 <varname>object</varname> 对象的属性和方法列表——你正在映射的列表。所以唯一新出现的部分就是在 &if; 后面的过滤表达式。</para> 449 449 <para>过滤表达式看上去很恐怖,其实不是。你已经知道了 <link linkend="apihelper.builtin.callable">&callable;</link>、<link linkend="apihelper.getattr.intro">&getattr;</link> 和 <link linkend="odbchelper.tuplemethods">∈</link>。正如你在 <link linkend="apihelper.getattr">前面的部分</link> 中看到的,如果 <varname>object</varname> 是一个模块,并且<varname>method</varname> 是上述模块中某个函数的名称,那么表达式 <literal>&apihelper_getattr;</literal> 将返回一个函数对象。</para> 450 <para>所以这个表达式接收一个名为 <varname>object</varname> 的对象,然后得到它的属性、方法、函数和其他部件的名称列表,接着过滤掉我们不关心的部件。执行过滤行为是通过对每个属性/方法/函数的名称调用 &getattr; 函数取得实际部件的引用,然后检查这些部件对象是否是可调用的,当然这些可调用的部件对象可能是方法或者函数,同时也可能是内置 (例如列表的 &pop; 方法)或者用户自定义的(例如 &odbchelper_modulename; 模块的 &odbchelper_function; 函数)。这里你不用关心其它的属性,如内置在每一个模块中的 &name; 属性。</para>450 <para>所以这个表达式接收一个名为 <varname>object</varname> 的对象,然后得到它的属性、方法、函数和其他部件的名称列表,接着过滤掉我们不关心的部件。执行过滤行为是通过对每个属性/方法/函数的名称调用 &getattr; 函数取得实际部件的引用,然后检查这些部件对象是否是可调用的,当然这些可调用的部件对象可能是方法或者函数,同时也可能是内置的(比如列表的 &pop; 方法)或者用户自定义的(比如 &odbchelper_modulename; 模块的 &odbchelper_function; 函数)。这里你不用关心其它的属性,如内置在每一个模块中的 &name; 属性。</para> 450 450 <itemizedlist role="furtherreading"> 451 451 <title>进一步阅读</title> … … 585 585 <calloutlist> 586 586 <callout arearefs="apihelper.lambda.1.2"> 587 <para>这是一个 &lambdafunction; 函数,完成成同上面普通函数相同的事情。注意这里的简短的语法:在参数列表周围没有括号,而且忽略了 <literal>return</literal> 关键字( ) (it is implied, since the entire function can only be one expression). 而且,该函数没有函数名称,但是可以将它赋值给一个变量进行调用。</para>587 <para>这是一个 &lambdafunction; 函数,完成成同上面普通函数相同的事情。注意这里的简短的语法:在参数列表周围没有括号,而且忽略了 <literal>return</literal> 关键字(隐含存在,因为整个函数只有一行). 而且,该函数没有函数名称,但是可以将它赋值给一个变量进行调用。</para> 587 587 </callout> 588 588 <callout arearefs="apihelper.lambda.1.3"> … … 595 595 <note id="tip.lambda"> 596 596 <title>&lambdafunction; 是可选的</title> 597 <para>&lambdafunction; 函数是一种风格问题。不一定非要使用它们;任何能够使用它们的地方,都可以定义一个单独的普通函数来进行替换。我将它们用在需要封装特殊的、非重用 的代码上 without littering my code with a lot of little one-line functions.</para>597 <para>&lambdafunction; 函数是一种风格问题。不一定非要使用它们;任何能够使用它们的地方,都可以定义一个单独的普通函数来进行替换。我将它们用在需要封装特殊的、非重用代码上,避免另我的代码充斥着大量单行函数。</para> 597 597 </note> 598 598 <section> … … 636 636 </informalexample> 637 637 <para><varname>processFunc</varname> 现在是一个函数,但是它到底是哪一个函数还要取决于 <varname>collapse</varname> 变量。如果 <varname>collapse</varname> 为真,<literal><varname>processFunc</varname>(<replaceable>string</replaceable>)</literal> 将压缩空白;否则 <literal><varname>processFunc</varname>(<replaceable>string</replaceable>)</literal> 将返回未改变的参数。</para> 638 <para>在一个不很健壮的语言中实现它,像 &vb;,你很有可能要创建一个函数,接受一个字符串参数和一个 <parameter>collapse</parameter> 参数,并使用 &if; 语句确定是否压缩空白,然后再返回相应的值。这种方式是低效的,因为函数可能需要处理每一种可能的情况。每次你调用它,它将不得不在给出你所想要的东西之前,判断是否要压缩空白。在 &python; 中,你可以将决策逻辑拿到函数外面,而定义一个裁减过的 &lambdafunction; 函数提供确切的(唯一的)你想要的。这种方式更为高效、更为优雅,而且很少引起那些令人讨厌 的(哦,想到那些参数就头昏)的错误。</para>638 <para>在一个不很健壮的语言中实现它,像 &vb;,你很有可能要创建一个函数,接受一个字符串参数和一个 <parameter>collapse</parameter> 参数,并使用 &if; 语句确定是否压缩空白,然后再返回相应的值。这种方式是低效的,因为函数可能需要处理每一种可能的情况。每次你调用它,它将不得不在给出你所想要的东西之前,判断是否要压缩空白。在 &python; 中,你可以将决策逻辑拿到函数外面,而定义一个裁减过的 &lambdafunction; 函数提供确切的(唯一的)你想要的。这种方式更为高效、更为优雅,而且很少引起那些令人讨厌(哦,想到那些参数就头昏)的错误。</para> 638 638 <itemizedlist role="furtherreading"> 639 639 <title>&lambdafunction; 函数进一步阅读</title> … … 650 650 <abstract> 651 651 <title/> 652 <para>最 一行代码是唯一还没有解释过的,它完成全部的工作。尽管如此,到目前为止工作都还很顺利,因为所需要的每件事都已经按照需求建立好了。所有的多米诺骨牌已经就位,到了将它们推倒的时候了。</para>652 <para>最后一行代码是唯一还没有解释过的,它完成全部的工作。但是现在工作已经简单了,因为所需要的每件事都已经按照需求建立好了。所有的多米诺骨牌已经就位,到了将它们推倒的时候了。</para> 652 652 </abstract> 653 653 <informalexample> 713 713 <para>在 &sql; 中,你必须使用 <literal>IS NULL</literal> 代替 <literal>= NULL</literal> 进行 null 值比较。在 &python;,你可以使用 <literal>== None</literal> 或者 <literal>is None</literal> 进行比较,但是 <literal>is None</literal> 更快。</para> 714 714 </note> 715 <para>现在你确保有了一个字符串,可以把这个字符串传给 <varname>processFunc</varname>,这个函数 <link linkend="apihelper.lambda">已经定义</link> 为了一个既可以压缩空白也可以不压缩空白的函数。现在你可以明白为什么使用 &str; 将 &none; 转化为一个字符串很重要了。<varname>processFunc</varname> 假设接收到一个字符串参数然后调用 &split; 方法,如果你传入 &none; ,将导致程序崩溃,因为 &none; 没有 &split; 方法。</para>715 <para>现在你确保有了一个字符串,可以把这个字符串传给 <varname>processFunc</varname>,这个函数 <link linkend="apihelper.lambda">已经定义</link> 是一个既可以压缩空白也可以不压缩空白的函数。现在你看出来为什么使用 &str; 将 &none; 转化为一个字符串很重要了。<varname>processFunc</varname> 假设接收到一个字符串参数然后调用 &split; 方法,如果你传入 &none; ,将导致程序崩溃,因为 &none; 没有 &split; 方法。</para> 715 715 <para>再往回走一步,你再一次使用了字符串格式化来连接 <varname>processFunc</varname> 的返回值 和 <varname>method</varname> 的 &ljust; 方法的返回值。&ljust; 是一个你之前没有见过的新字符串方法。</para> 716 716 <example>