Changeset 919

Show
Ignore:
Timestamp:
Sun Mar 19 00:36:17 2006
Author:
osmond
Message:

update

Files:

Legend:

Unmodified
Added
Removed
Modified
  • zh-translations/branches/diveintopython-zh-5.4/zh-cn/xml/plural.xml

    r918 r919  
    19 19 <listitem><para>如果一切规则都不适用,就只添加 S 并祈祷不会错。</para></listitem>  
    20 20 </orderedlist>  
    21   <para>(我知道有很多例外情况, 比如: <quote>Man</quote> 变成 <quote>men</quote>, <quote>woman</quote> 变成 <quote>women</quote>,但是, <quote>human</quote> 却变成 <quote>humans</quote>。 <quote>Mouse</quote> 变成 <quote>mice</quote>, <quote>louse</quote> 变成 <quote>lice</quote>, 但是, <quote>house</quote> 却变成 <quote>houses</quote>。 <quote>Knife</quote> 变成 <quote>knives</quote>, <quote>wife</quote> 变成 <quote>wives</quote>,但是 <quote>lowlife</quote> 却变成 <quote>lowlifes</quote>。 更不要说那些复数不需要变化的词了,比如 <quote>sheep</quote>, <quote>deer</quote>, and <quote>haiku</quote>。)</para>  
      21 <para>(我知道有很多例外情况, 比如: <quote>Man</quote> 变成 <quote>men</quote>, <quote>woman</quote> 变成 <quote>women</quote>,但是, <quote>human</quote> 却变成 <quote>humans</quote>。 <quote>Mouse</quote> 变成 <quote>mice</quote>, <quote>louse</quote> 变成 <quote>lice</quote>, 但是, <quote>house</quote> 却变成 <quote>houses</quote>。 <quote>Knife</quote> 变成 <quote>knives</quote>, <quote>wife</quote> 变成 <quote>wives</quote>,但是 <quote>lowlife</quote> 却变成 <quote>lowlifes</quote>。 更不要说那些复数根本就不需要变化的词了,比如 <quote>sheep</quote>, <quote>deer</quote> 和 <quote>haiku</quote>。)</para>  
    21 21 <para>其他的语言当然完全不同。</para>  
    22 22 <para>让我们来设计一个复数化名词的模块吧! 从英语名词开始,仅考虑上面的四种规则,但是记得你将来需要不断添加规则,更可能最后添加进更多的语言。</para>  
     
    72 72 </callout>  
    73 73 <callout arearefs="plural.stage1.2.2">  
    74   <para>好的,现在找出 <literal>a</literal>, <literal>b</literal>,或者  <literal>c</literal>并以 <literal>o</literal> 取代之。 <literal>Mark</literal> 就变成 <literal>Mork</literal> 了。</para>  
      74 <para>好的,现在找出 <literal>a</literal>, <literal>b</literal>,或者  <literal>c</literal> 并以 <literal>o</literal> 取代之。 <literal>Mark</literal> 就变成 <literal>Mork</literal> 了。</para>  
    74 74 </callout>  
    75 75 <callout arearefs="plural.stage1.2.3">  
     
    78 78 </callout>  
    79 79 <callout arearefs="plural.stage1.2.4">  
    80   <para>你可能认为它可以将 <literal>caps</literal> 变成 <literal>oaps</literal>,但���是这样。 <literal>re.sub</literal> 替换 <emphasis>所有</emphasis> 的匹配项,并不只是第一个匹配项。 因此正则表达式将会把 <literal>caps</literal> 变成 <literal>oops</literal>。因为, <literal>c</literal> 和 <literal>a</literal> 都被转换为 <literal>o</literal>了。</para>  
      80 <para>你可能认为它可以将 <literal>caps</literal> 变成 <literal>oaps</literal>,但���实并非如此。 <literal>re.sub</literal> 替换 <emphasis>所有</emphasis> 的匹配项,并不只是第一个匹配项。 因此正则表达式将会把 <literal>caps</literal> 变成 <literal>oops</literal>。因为, <literal>c</literal> 和 <literal>a</literal> 都被转换为 <literal>o</literal>了。</para>  
    80 80 </callout>  
    81 81 </calloutlist>  
     
    102 102 </callout>  
    103 103 <callout arearefs="plural.stage1.3.2">  
    104   <para>仔细看看,这是另一个新的内容。 <literal>^</literal> 是方括号里面的第一个字符,这有特别的含义:否定。  <literal>[^abc]</literal> 意味着 <quote> 除 <literal>a</literal>、 <literal>b</literal>、 和 <literal>c</literal> <emphasis>以外的</emphasis> 任意单字符</quote>。 所以, <literal>[^aeioudgkprt]</literal> 意味着除 <literal>a</literal>、 <literal>e</literal>、 <literal>i</literal>、 <literal>o</literal>、 <literal>u</literal>、 <literal>d</literal>、 <literal>g</literal>、 <literal>k</literal>、 <literal>p</literal>、 <literal>r</literal> 和 <literal>t</literal> 以外的任意字符。 这个字符之后应该跟着一个 <literal>h</literal>,然后是字符串的结尾。你在寻找的以发音的 H 结尾的单词。</para>  
      104 <para>仔细看看,这是另一个新的内容。 <literal>^</literal> 是方括号里面的第一个字符,这有特别的含义:否定。  <literal>[^abc]</literal> 意味着 <quote> 除 <literal>a</literal>、 <literal>b</literal>、 和 <literal>c</literal> <emphasis>以外的</emphasis> 任意单字符</quote>。 所以, <literal>[^aeioudgkprt]</literal> 意味着除 <literal>a</literal>、 <literal>e</literal>、 <literal>i</literal>、 <literal>o</literal>、 <literal>u</literal>、 <literal>d</literal>、 <literal>g</literal>、 <literal>k</literal>、 <literal>p</literal>、 <literal>r</literal> 和 <literal>t</literal> 以外的任意字符。 这个字符之后应该跟着一个 <literal>h</literal>,然后是字符串的结尾。你在寻找的以发音的 H 结尾的单词。</para>  
    104 104 </callout>  
    105 105 <callout arearefs="plural.stage1.3.3">  
     
    149 149 </callout>  
    150 150 <callout arearefs="plural.stage1.5.2">  
    151   <para>顺便提一下,可以将两个正则表达式(一个确定规则适用与否,一个应用规则)合并在一起成为一个正则表达式。 这便是合并后的样子。 它的大部分已经很熟悉:你应用的是在 <xref linkend="re.phone"/> 学过的记忆组(remembered group)记住 <literal>y</literal> 之前的字符。然后���替换字符串,你使用一个新的语法 <literal>\1</literal>,这意味着: <quote>嘿!记得前面的第一个组吗? 把它放这儿</quote>。 就此而言,记住了 <literal>y</literal> 之前的 <literal>c</literal> ,然后你做替换工作,你将 <literal>c</literal> 替换到 <literal>c</literal> 的位置,并将 <literal>ies</literal> 替换到 <literal>y</literal> 的位置。 (如果你有不只一个组则可以使用 <literal>\2</literal> 或者 <literal>\3</literal> 等等。)</para>  
      151 <para>顺便提一下,可以将两个正则表达式(一个确定规则适用与否,一个应用规则)合并在一起成为一个正则表达式。 这便是合并后的样子。 它的大部分已经很熟悉:你应用的是在 <xref linkend="re.phone"/> 学过的记忆组(remembered group)记住 <literal>y</literal> 之前的字符。然后���替换字符串,你使用一个新的语法 <literal>\1</literal>,这意味着: <quote>嘿!记得前面的第一个组吗? 把它放这儿</quote>。 就此而言,记住了 <literal>y</literal> 之前的 <literal>c</literal> ,然后你做替换工作,你将 <literal>c</literal> 替换到 <literal>c</literal> 的位置,并将 <literal>ies</literal> 替换到 <literal>y</literal> 的位置。 (如果你有不只一个组则可以使用 <literal>\2</literal> 或者 <literal>\3</literal> 等等。)</para>  
    151 151 </callout>  
    152 152 </calloutlist>  
     
    201 201 <calloutlist>  
    202 202 <callout arearefs="plural.stage2.1.1">  
    203   <para>这个版本看起来更加复杂 (至少是长了),但做的工作没有变化:试图顺序匹配四种不同规则,并在匹配时应用恰当的正则表达式。 不同之处在于,每个独立的匹配和应用规则都在自己的[todo]方程中定义,并且这些方程列于 <varname>rules</varname> 变量这个元组的元组之中。</para>  
      203 <para>这个版本看起来更加复杂 (至少是长了),但做的工作没有变化:试图顺序匹配四种不同规则,并在匹配时应用恰当的正则表达式。 不同之处在于,每个独立的匹配和应用规则都在自己的函数中定义,并且这些函数列于 <varname>rules</varname> 变量这个元组的元组之中。</para>  
    203 203 </callout>  
    204 204 <callout arearefs="plural.stage2.1.2">  
     
    229 229 </programlisting>  
    230 230 </example>  
    231   <para>这里的好处在于 <function>plural</function> 函数现在被简化了。 它以普通的方法反复使用其它地方定义的规则。 获得一个匹配规则,匹配吗? 调用并应用规则。 规则可以在任意地方以任意方法定义, <function>plural</function> 函数对此并不[todo](关心?)在乎。</para>  
    232   <para>现在,添加这个抽象过程值得吗? 嗯... 还不值。 让我们看看如何[todo]向方程添加一个新的规则。 啊哈,在先前的范例中,需要向 <function>plural</function> 函数添加一个 &if; 语句;在这个例子中,需要增加两个函数: <function>match_foo</function> 和 <function>apply_foo</function>,然后更新 <varname>rules</varname> 列表指定在什么相对位置调用这个新匹配和新规则应用。</para>  
      231 <para>这里的好处在于 <function>plural</function> 函数现在被简化了。 它以普通的方法反复使用其它地方定义的规则。 获得一个匹配规则,匹配吗? 调用并应用规则。 规则可以在任意地方以任意方法定义, <function>plural</function> 函数对此并不关心。</para>  
      232 <para>现在,添加这个抽象过程值得吗? 嗯... 还不值。 让我们看看如何向函数添加一个新的规则。 啊哈,在先前的范例中,需要向 <function>plural</function> 函数添加一个 &if; 语句;在这个例子中,需要增加两个函数: <function>match_foo</function> 和 <function>apply_foo</function>,然后更新 <varname>rules</varname> 列表指定在什么相对位置调用这个新匹配和新规则应用。</para>  
    233 233 <para>这其实不过是步入下一节的一个基石。让我们继续。</para>  
    234 234 </section>  
     
    239 239 <abstract>  
    240 240 <title/>  
    241   <para>将每个匹配和规则应用分别制作成函数没有必要。 你从来不会直接调用它们:你把它们定义于 <varname>rules</varname> 列表之中并从那里调用它们。 让我们隐去他们的函数名而抓住规则定义主线。</para>  
      241 <para>将每个匹配和规则应用分别制作成函数没有必要。 你从来不会直接调用它们:你把它们定义于 <varname>rules</varname> 列表之中并从那里调用它们。 让我们隐去他们的函数名而抓住规则定义主线。</para>  
    241 241 </abstract>  
    242 242 <example>  
     
    262 262 </calloutlist>  
    263 263 </example>  
    264   <para>现在添加一条新的规则,所有你要做的就是直接在 <varname>rules</varname> 列表之中定义函数:一个匹配规则,一个应用规则。 这样内嵌的规则方程定义方法使得没必要的重复很容易发现。 你有四对函数,它们采用相同的模式。 匹配函数就是调用 <function>re.search</function>,应用函数就是调用 <function>re.sub</function>。 让我们提炼出这些共同点。</para>  
      264 <para>现在添加一条新的规则,所有你要做的就是直接在 <varname>rules</varname> 列表之中定义函数:一个匹配规则,一个应用规则。 这样内嵌的规则函数定义方法使得没必要的重复很容易被发现。 你有四对函数,它们采用相同的模式。 匹配函数就是调用 <function>re.search</function>,应用函数就是调用 <function>re.sub</function>。 让我们提炼出这些共同点。</para>  
    264 264 </section>  
    265 265  
     
    284 284 <calloutlist>  
    285 285 <callout arearefs="plural.stage4.1.1">  
    286   <para><function>buildMatchAndApplyFunctions</function> 是一个动态生成其它函数的函数。 它将 <varname>pattern</varname>, <varname>search</varname> 和 <varname>replace</varname> ([todo]实际上是把一个元组,但很快就会变得不止于此),通过使用 &lambdafunction; 语法构建一个接受单参数(<varname>word</varname>)并以传递给 <function>buildMatchAndApplyFunctions</function> 的 <varname>pattern</varname> 和 传递给新函数的 <varname>word</varname> 调用 <function>re.search</function> 的匹配函数! 哇塞!</para>  
      286 <para><function>buildMatchAndApplyFunctions</function> 是一个动态生成其它函数的函数。 它将 <varname>pattern</varname>, <varname>search</varname> 和 <varname>replace</varname> (实际上是一个元组,但很快就会变得不止于此),通过使用 &lambdafunction; 语法构建一个接受单参数(<varname>word</varname>)并以传递给 <function>buildMatchAndApplyFunctions</function> 的 <varname>pattern</varname> 和 传递给新函数的 <varname>word</varname> 调用 <function>re.search</function> 的匹配函数! 哇塞!</para>  
    286 286 </callout>  
    287 287 <callout arearefs="plural.stage4.1.2">  
    288   <para>构建应用规则函数的方法相同。 应用规则函数是一个接受单参数并以传递给 <function>buildMatchAndApplyFunctions</function> 的 <varname>search</varname> 和 <varname>replace</varname> 以及传递给这个应用规则函数的 <varname>word</varname> 调用 <function>re.sub</function> 的函数。在一个动态函数中应用外部参数值的技术被称作 <emphasis>[todo]闭宝(closures)</emphasis>。你实际上是在应用规则函数中定义常数:接受一个参数(<varname>word</varname>),但随后它与定义应用规则函数时设置的另外两个值 (<varname>search</varname> 和 <varname>replace</varname>)一起工作。</para>  
      288 <para>构建应用规则函数的方法相同。 应用规则函数是一个接受单参数并以传递给 <function>buildMatchAndApplyFunctions</function> 的 <varname>search</varname> 和 <varname>replace</varname> 以及传递给这个应用规则函数的 <varname>word</varname> 调用 <function>re.sub</function> 的函数。在一个动态函数中应用外部参数值的技术被称作 <emphasis>闭合(closures)</emphasis>。你实际上是在应用规则函数中定义常数:接受一个参数(<varname>word</varname>),但随后它与定义应用规则函数时设置的另外两个值 (<varname>search</varname> 和 <varname>replace</varname>)一起工作。</para>  
    288 288 </callout>  
    289 289 <callout arearefs="plural.stage4.1.3">  
     
    303 303 <calloutlist>  
    304 304 <callout arearefs="plural.stage4.2.1">  
    305   <para>我们的复数化规则现在被定义成一组字符串(不是函数)。 第一个字符串是你在调用 <function>re.search</function> 时使用的正则表达式;第二个和第三个字符串是你在通过调用 <function>re.sub</function> 来应用规则将名词变为复数时使用的搜索和替换表达式。 </para>  
      305 <para>我们的复数化规则现在被定义成一组字符串(不是函数)。 第一个字符串是你在调用 <function>re.search</function> 时使用的正则表达式;第二个和第三个字符串是你在通过调用 <function>re.sub</function> 来应用规则将名词变为复数时使用的搜索和替换表达式。 </para>  
    305 305 </callout>  
    306 306 <callout arearefs="plural.stage4.2.2">  
     
    361 361 </callout>  
    362 362 </calloutlist>  
    363   <para>现在,让我们回过头看一看这个元组自动展开技巧的必要性。 <varname>patterns</varname> 是一个元组列表,并且每个元组都有三个元���。调用 <literal>map(buildMatchAndApplyFunctions, patterns)</literal>,这并<emphasis>不</emphasis> 意味着是以三个参数调用 <function>buildMatchAndApplyFunctions</function>。 使用 <function>map</function> 映射一个列表到函数时,通常使用单参数:列表中的每个元素。 就 <varname>patterns</varname> 而言, 列表的每个元素都是一个元组,所以 <function>buildMatchAndApplyFunctions</function> 经常是以元组来调用,在 <function>buildMatchAndApplyFunctions</function> 中使用元组自动展开技巧将元素赋值给可以被使用的变量。</para>  
      363 <para>现在,让我们回过头看一看这个元组自动展开技巧的必要性。 <varname>patterns</varname> 是一个元组列表,并且每个元组都有三个元���。调用 <literal>map(buildMatchAndApplyFunctions, patterns)</literal>,这并<emphasis>不</emphasis> 意味着是以三个参数调用 <function>buildMatchAndApplyFunctions</function>。 使用 <function>map</function> 映射一个列表到函数时,通常使用单参数:列表中的每个元素。 就 <varname>patterns</varname> 而言, 列表的每个元素都是一个元组,所以 <function>buildMatchAndApplyFunctions</function> 经常是以元组来调用,在 <function>buildMatchAndApplyFunctions</function> 中使用元组自动展开技巧将元素赋值给可以被使用的变量。</para>  
    363 363 </example>  
    364 364 </section>  
     
    414 414 </callout>  
    415 415 <callout arearefs="plural.stage5.1.5">  
    416   <para>如果 <varname>patterns</varname> 是一个元组列表,那么 <varname>rules</varname> 就可以通过一个个调用 <function>buildRule</function> 动态地声称函数列表。 调用 <function>buildRule(('[sxz]$', '$', 'es'))</function> 返回一个接受单参数 <varname>word</varname> 的函数。 当返回的函数被调用,则将执行 <literal>re.search('[sxz]$', word) 和 re.sub('$', 'es', word)</literal>。</para>  
      416 <para>如果 <varname>patterns</varname> 是一个元组列表,那么 <varname>rules</varname> 就可以通过一个个调用 <function>buildRule</function> 动态地生成函数列表。 调用 <function>buildRule(('[sxz]$', '$', 'es'))</function> 返回一个接受单参数 <varname>word</varname> 的函数。 当返回的函数被调用,则将执行 <literal>re.search('[sxz]$', word) 和 re.sub('$', 'es', word)</literal>。</para>  
    416 416 </callout>  
    417 417 <callout arearefs="plural.stage5.1.6">  
    418   <para>因为你现在构建的是一个匹配和规则应用���一的函数,你需要分别调用它们。 仅仅是调用函数,如果返回了内容,那么返回的便是复数;如果没有返回(也就是返回了&none;),那么该规则未能匹配,那么应该尝试其他规则。</para>  
      418 <para>因为你现在构建的是一个匹配和规则应用���一的函数,你需要分别调用它们。 仅仅是调用函数,如果返回了内容,那么返回的便是复数;如果没有返回(也就是返回了&none;),那么该规则未能匹配,那么应该尝试其他规则。</para>  
    418 418 </callout>  
    419 419 </calloutlist>  
     
    431 431 <abstract>  
    432 432 <title/>  
    433   <para>现在你已准备好探讨生成器(Generator )了.</para>  
      433 <para>现在你已准备好探讨生成器(Generator )了</para>  
    433 433 </abstract>  
    434 434 <example>  
     
    478 478 </callout>  
    479 479 <callout arearefs="plural.stage6.2.2">  
    480   <para>建立一个 <function>make_counter</function> 生成器的实例,[todo]只需像调用任何其他函数。 注意这并没有真正的执行函数代码。 <function>make_counter</function> 第一行的 &print; 语句是一个语句,但是没有任何内容被打印就可以说明这一点。</para>  
      480 <para>建立一个 <function>make_counter</function> 生成器的实例,并像调用任何其他函数一样调用之。 注意这并没有真正的执行函数代码。 <function>make_counter</function> 第一行的 &print; 语句是一个语句,但是没有任何内容被打印就可以说明这一点。</para>  
    480 480 </callout>  
    481 481 <callout arearefs="plural.stage6.2.3">  
     
    529 529 </callout>  
    530 530 <callout arearefs="plural.stage6.4.2">  
    531   <para>每轮 &for; 循环 <varname>n</varname> 都从 <function>fibonacci</function> 的 &yield; 语句获得一个新的值。 当 <function>fibonacci</function> 超出数字限定(<varname>a</varname>达到超过<varname>max</varname> 你在这里限定的 <literal>1000</literal>)很自然地退出 &for; 循环。</para>  
      531 <para>每轮 &for; 循环 <varname>n</varname> 都从 <function>fibonacci</function> 的 &yield; 语句获得一个新的值。 当 <function>fibonacci</function> 超出数字限定(<varname>a</varname> 超过 <varname>max</varname> 你在这里限定的是 <literal>1000</literal>)很自然地退出 &for; 循环。</para>  
    531 531 </callout>  
    532 532 </calloutlist>  
     
    549 549 <calloutlist>  
    550 550 <callout arearefs="plural.stage6.5.1">  
    551   <para><literal>for line in file(...)</literal> 是从文件中一行行读取的通用方法,每次一行。 它正常工作是因为 <emphasis><function>file</function> 实际上返回一个生成器</emphasis>, 它的 <function>next()</function> 方法返回文件中的下一行。 简直太酷了,光是想想就让我满头大汗。</para>  
      551 <para><literal>for line in file(...)</literal> 是从文件中一行行读取的通用方法,每次一行。 它正常工作是因为 <emphasis><function>file</function> 实际上返回一个生成器</emphasis>, 它的 <function>next()</function> 方法返回文件中的下一行。 简直太酷了,光是想想就让我满头大汗。</para>  
    551 551 </callout>  
    552 552 <callout arearefs="plural.stage6.5.2">  
    585 585 <listitem><para>构建 <link linkend="plural.stage6">生成器</link>,进行逻辑递增操作并在每次调用时返回不同值的恢复执行函数。</para></listitem>  
    586 586 </itemizedlist>  
    587   <para>抽象化,动态构建函数,构建闭合以及应用生成器能够使你的代码更加简单���、可读化、灵活化。 在简洁和功能实现是需要你从中平衡的。</para>  
      587 <para>抽象化,动态构建函数,构建闭合以及应用生成器能够使你的代码更加简单���、可读化、灵活化。 你需要在简洁和功能实现中进行平衡。</para>  
    587 587 </section>  
    588 588 </chapter>