Changeset 251
- Timestamp:
- Mon Dec 12 15:22:03 2005
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
-
zh-translations/branches/diveintopython-zh-5.4/zh-cn/xml/entities.xml
r249 r251 243 243 <!ENTITY for "<literal>for</literal>"> 244 244 <!ENTITY while "<literal>while</literal>"> 245 <!ENTITY import "<literal> 重要的</literal>">245 <!ENTITY import "<literal>import</literal>"> 245 245 <!ENTITY require "<literal>require</literal>"> 246 246 <!ENTITY yield "<literal>yield</literal>"> -
zh-translations/branches/diveintopython-zh-5.4/zh-cn/xml/fileinfo.xml
r244 r251 224 224 <para>在 &python; 中的 &pass; 语句就象 &java; 或 &c; 中的大括号空集(<literal>{}</literal>)。</para> 225 225 </note> 226 <para> Of course, realistically, most classes will be inherited from other classes, and they will define their own class methods and attributes. But as you've just seen, there is nothing that a class absolutely must have, other than a name. In particular, &cpp; programmers may find it odd that &python; classes don't have explicit constructors and destructors. &python; classes do have something similar to a constructor: the &init; method.</para>226 <para>当然,实际上大多数的类都是从其它的类继承来的,并且它们会定义自已的类方法和属性。但是就象你刚才看到的,除了名字以外,类没有什么必须要具有的。特别是,&cpp; 程序员可能会感到奇怪,&python; 的类没有显示的构造函数和析构函数。&python; 类的确存在与构造函数相似的东西: &init; 方法。</para> 226 226 <example id="fileinfo.class.example"> 227 <title> Defining the &fileinfo_classname; Class</title>227 <title>定义 &fileinfo_classname; 类</title> 227 227 <programlisting> 228 228 &fileinfo_importuserdict; … … 233 233 <calloutlist> 234 234 <callout arearefs="fileinfo.class.2.1"> 235 <para> In &python;, the ancestor of a class is simply listed in parentheses immediately after the class name. So the <classname>FileInfo</classname> class is inherited from the <classname>UserDict</classname> class (which was <link linkend="fileinfo.fromimport">imported from the <filename class="headerfile">UserDict</filename> module</link>). <classname>UserDict</classname> is a class that acts like a dictionary, allowing you to essentially subclass the dictionary datatype and add your own behavior. (There are similar classes <classname>UserList</classname> and <classname>UserString</classname> which allow you to subclass lists and strings.) There is a bit of black magic behind this, which you will demystify later in this chapter when you explore the <classname>UserDict</classname> class in more depth.</para>235 <para>在 &python; 中,类的基类只是简单地列在类名后面的小括号里。所以 <classname>FileInfo</classname> 类是从 <classname>UserDict</classname> 类 (它是从 <link linkend="fileinfo.fromimport"><filename class="headerfile">UserDict</filename> 模块导进来的</link>)继承来的。<classname>UserDict</classname> 是一个象字典一样工作的类,它允许你完全子类化字典数据类型,同时增加你自已的行为。(也存在相似的类 <classname>UserList</classname> 和 <classname>UserString</classname> ,它们允许你子类化列表和字符串。)(译注:在 2.2 之后已经可以从 dict, list 来派生子类了) 在这个类的背后有一些“巫术”,我们将在本章的后面,随着更进一步地研究 <classname>UserDict</classname> 类,揭开这些秘密。</para> 235 235 </callout> 236 236 </calloutlist> 237 237 </example> 238 238 <note id="compare.extends.java" role="compare" vendor="java"> 239 <title>&python; &vs; &java;: Ancestors</title> 240 <para>In &python;, the ancestor of a class is simply listed in parentheses immediately after the class name. There is no special keyword like <literal>extends</literal> in &java;.</para> 239 <title>在 &python; 中,类的基类只是简单地列在类名后面的小括号里。不象在 &java; 中有一个特殊的象 <literal>extends</literal> 的关键字。</para> 241 240 </note> 242 <para>&python; supports multiple inheritance. In the parentheses following the class name, you can list as many ancestor classes as you like, separated by commas.</para>241 <para>&python; 支持多重继承。在类名后面的小括号中,你可以列出许多你想要的类名,以逗号分隔。</para> 242 241 <section> 243 <title>Initializing and Coding Classes</title> 244 <para>This example shows the initialization of the &fileinfo_classname; class using the &init; method.</para> 242 <title>初始化并开始类编码</title> 243 <para>本例演示了使用 &init; 方法来进行 &fileinfo_classname; 类的初始化。</para> 245 244 <example id="fileinfo.init.example"> 246 <title> Initializing the&fileinfo_classname; Class</title>245 <title>初始化 &fileinfo_classname; Class</title> 246 245 <programlisting> 247 246 &fileinfo_filedef; … … 253 252 <calloutlist> 254 253 <callout arearefs="fileinfo.class.2.2"> 255 <para> Classes can (and <link linkend="tip.docstring">should</link>) have &docstring;s too, just like modules and functions.</para>254 <para>类也可以 (并且 <link linkend="tip.docstring">应该</link>) 有 &docstring;s ,就象方法和函数一样。</para> 255 254 </callout> 256 255 <callout arearefs="fileinfo.class.2.3"> 257 <para>&init; is called immediately after an instance of the class is created. It would be tempting but incorrect to call this the constructor of the class. It's tempting, because it looks like a constructor (by convention, &init; is the first method defined for the class), acts like one (it's the first piece of code executed in a newly created instance of the class), and even sounds like one (<quote>init</quote> certainly suggests a constructor-ish nature). Incorrect, because the object has already been constructed by the time &init; is called, and you already have a valid reference to the new instance of the class. But &init; is the closest thing you're going to get to a constructor in &python;, and it fills much the same role.</para>256 <para>&init; 在类的实例创建后被立即调用。它可能会引诱你称之为类的构造函数,但这种说法并不正确。说它引诱,是因为它看上去象(按照习惯, &init; 是类中第一个定义的方法),行为也象(在一个新创建的类实例中,它是首先被执行的代码),并且叫起来也象(<quote>init</quote>当然意味着构造的本性)。说它不正确,是因为对象在调用 &init; 时已经被构造出来了,你已经有了一个对类的新实例的有效引用。但 &init; 是在 &python; 中你可以得到的最接近构造函数的东西,并且它也扮演着非常相同的角色。</para> 257 256 </callout> 258 257 <callout arearefs="fileinfo.class.2.4"> 259 <para> The first argument of every class method, including &init;, is always a reference to the current instance of the class. By convention, this argument is always named &self;. In the &init; method, &self; refers to the newly created object; in other class methods, it refers to the instance whose method was called. Although you need to specify &self; explicitly when defining the method, you do <emphasis>not</emphasis> specify it when calling the method; &python; will add it for you automatically.</para>258 <para>每个类方法的第一个参数,包括 &init;,都是指向类的当前实例的引用。按照习惯这个参数总是被叫为 &self;。在 &init; 方法中,&self; 指向新创建的对象;在其它的类方法中,它指向方法被调用的类实例。尽管当定义方法时你需要明确指定 &self;,但在调用方法时,你<emphasis>不</emphasis>用指定它,&python;会替你自动加上的。</para> 259 258 </callout> 260 259 <callout arearefs="fileinfo.class.2.5"> … … 268 267 <note id="compare.self.java" role="compare" vendor="java"> 269 268 <title>&python; &vs; &java;: &self;</title> 270 <para> By convention, the first argument of any &python; class method (the reference to the current instance) is called &self;. This argument fills the role of the reserved word &this; in &cpp; or &java;, but &self; is not a reserved word in &python;, merely a naming convention. Nonetheless, please don't call it anything but &self;; this is a very strong convention.</para>269 <para>习惯上,任何 &python; 类方法的第一个参数(对当前实例的引用)都叫做 &self;。这个参数扮演着 &cpp; 或 &java; 中的保留字 &this; 的角色,但 &self; 在 &python; 中并不是一个保留字,它只是一个命名习惯。虽然如此,也请除了 &self; 之外不要使用其它的名字,这是一个非常坚固的习惯。</para> 270 269 </note> 271 270 <example id="fileinfo.init.code.example"> 272 <title> Coding the &fileinfo_classname; Class</title>271 <title>编写 &fileinfo_classname; 类</title> 272 271 <programlisting> 273 272 &fileinfo_filedef; … … 281 280 <calloutlist> 282 281 <callout arearefs="fileinfo.class.2.6"> 283 <para> Some pseudo-object-oriented languages like &powerbuilder; have a concept of <quote>extending</quote> constructors and other events, where the ancestor's method is called automatically before the descendant's method is executed. &python; does not do this; you must always explicitly call the appropriate method in the ancestor class.</para>282 <para>一些伪面向对象语言,象 &powerbuilder; 有一种<quote>扩展</quote>构造函数和其它事件的概念,即父类的方法在子类的方法执行前被自动调用。&python;不是这样,你必须显示地调用在父类中的适合方法。</para> 283 282 </callout> 284 283 <callout arearefs="fileinfo.class.2.7"> 285 <para> I told you that this class acts like a dictionary, and here is the first sign of it. You're assigning the argument <varname>filename</varname> as the value of this object's <literal>name</literal> key.</para>284 <para>我告诉过你,这个类的象字典一样工作,那么这里就是第一个印象。我们将参数 <varname>filename</varname> 赋值给对象 <literal>name</literal> 关键字,作为它的值。</para> 285 284 </callout> 286 285 <callout arearefs="fileinfo.class.2.8"> 287 <para> Note that the &init; method never returns a value.</para>286 <para>注意 &init; 方法从不返回一个值。</para> 287 286 </callout> 288 287 </calloutlist> 293 292 </section> 294 293 <section> 295 <title>Knowing When to Use &self; and &init;</title> 296 <para>When defining your class methods, you <emphasis>must</emphasis> explicitly list &self; as the first argument for each method, including &init;. When you call a method of an ancestor class from within your class, you <emphasis>must</emphasis> include the &self; argument. But when you call your class method from outside, you do not specify anything for the &self; argument; you skip it entirely, and &python; automatically adds the instance reference for you. I am aware that this is confusing at first; it's not really inconsistent, but it may appear inconsistent because it relies on a distinction (between bound and unbound methods) that you don't know about yet.</para> 297 <para>Whew. I realize that's a lot to absorb, but you'll get the hang of it. All &python; classes work the same way, so once you learn one, you've learned them all. If you forget everything else, remember this one thing, because I promise it will trip you up:</para> 294 <title>了解何时去使用 &self; 和 &init;</title> 295 <para>当定义你自已的类方法时,你<emphasis>必须</emphasis>明确将 &self; 作为每个方法的第一个参数列出,包括 &init;。当从你的类中调用一个父类的一个方法时,你必须包括 &self; 参数。但当你从类的外部调用你的类方法时,你不必对 &self; 参数指定任何值;你完全将其忽略,而 &python; 会自动地替你增加实例的引用。我知道刚开始这有些混乱,它并不是自相矛盾的,因为它依靠于一个你还不了解的区别(在绑定与非绑定方法之间),故看上去是矛盾的。</para> 296 <para>噢。我知道有很多知识需要吸收,但是你要掌握它。所有的 &python; 类以相同的方式工作,所以一旦你学会了一个,就是学会了全部。如果你忘了别的任何事,也要记住这件事,因为我认定它会让你出错:</para> 298 297 <note id="tip.initoptional"> 299 <title>&init; Methods</title> 300 <para>&init; methods are optional, but when you define one, you must remember to explicitly call the ancestor's &init; method (if it defines one). This is more generally true: whenever a descendant wants to extend the behavior of the ancestor, the descendant method must explicitly call the ancestor method at the proper time, with the proper arguments.</para> 298 <title>&init; 方法</title> 299 <para>&init; 方法是可选的,但是一旦你定义了,就必须记得显示调用父类的 &init; 方法(如果它定义了的话)。这样更是正确的:无论何时子类想扩展父类的行为,后代方法必须在适当的时机,使用适当的参数,显式调用父类方法。</para> 301 300 </note> 302 301 <itemizedlist role="furtherreading"> 303 <title>Further Reading on &python; Classes</title> 304 <listitem><para>&learningtoprogram; has a gentler <ulink url="&url_learningtoprogram;tutclass.htm">introduction to classes</ulink>.</para></listitem> 305 <listitem><para>&howtothink; shows how to <ulink url="&url_howtothink;chap12.htm">use classes to model compound datatypes</ulink>.</para></listitem> 306 <listitem><para>&pythontutorial; has an in-depth look at <ulink url="&url_pythontutorial;node11.html">classes, namespaces, and inheritance</ulink>.</para></listitem> 307 <listitem><para>&pythonknowledgebase; answers <ulink url="&url_pythonknowledgebase;index.phtml/fid/242">common questions about classes</ulink>.</para></listitem> 302 <title>进一步阅读关于 &python; 类</title> 303 <listitem><para>&learningtoprogram; 有优雅的 <ulink url="&url_learningtoprogram;tutclass.htm">类的介绍</ulink>。</para></listitem> 304 <listitem><para>&howtothink; 展示了如何 <ulink url="&url_howtothink;chap12.htm">使用类来实现复合数据类型模型</ulink>。</para></listitem> 305 <listitem><para>&pythontutorial; 深入考虑了 <ulink url="&url_pythontutorial;node11.html">类、名字空间和继承</ulink>。</para></listitem> 306 <listitem><para>&pythonknowledgebase; 回答了 <ulink url="&url_pythonknowledgebase;index.phtml/fid/242">关于类的常见问题</ulink>。</para></listitem> 308 307 </itemizedlist> 309 308 </section>