# SOME DESCRIPTIVE TITLE. # Copyright (C) 2001-2025, Python Software Foundation # This file is distributed under the same license as the Python package. # FIRST AUTHOR , YEAR. # # Translators: # python-doc bot, 2025 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Python 3.10\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-02-14 16:07+0000\n" "PO-Revision-Date: 2025-09-22 15:58+0000\n" "Last-Translator: python-doc bot, 2025\n" "Language-Team: Chinese (China) (https://app.transifex.com/python-doc/teams/5390/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: zh_CN\n" "Plural-Forms: nplurals=1; plural=0;\n" #: ../../tutorial/classes.rst:5 msgid "Classes" msgstr "类" #: ../../tutorial/classes.rst:7 msgid "" "Classes provide a means of bundling data and functionality together. " "Creating a new class creates a new *type* of object, allowing new " "*instances* of that type to be made. Each class instance can have " "attributes attached to it for maintaining its state. Class instances can " "also have methods (defined by its class) for modifying its state." msgstr "" "类提供了把数据和功能绑定在一起的方法。创建新类时创建了新的对象 *类型*,从而能够创建该类型的新 " "*实例*。实例具有能维持自身状态的属性,还具有能修改自身状态的方法(由其所属的类来定义)。" #: ../../tutorial/classes.rst:13 msgid "" "Compared with other programming languages, Python's class mechanism adds " "classes with a minimum of new syntax and semantics. It is a mixture of the " "class mechanisms found in C++ and Modula-3. Python classes provide all the " "standard features of Object Oriented Programming: the class inheritance " "mechanism allows multiple base classes, a derived class can override any " "methods of its base class or classes, and a method can call the method of a " "base class with the same name. Objects can contain arbitrary amounts and " "kinds of data. As is true for modules, classes partake of the dynamic " "nature of Python: they are created at runtime, and can be modified further " "after creation." msgstr "" "和其他编程语言相比,Python 的类只使用了很少的新语法和语义。Python 的类有点类似于 C++ 和 Modula-3 " "中类的结合体,而且支持面向对象编程(OOP)的所有标准特性:类的继承机制支持多个基类、派生的类能覆盖基类的方法、类的方法能调用基类中的同名方法。对象可包含任意数量和类型的数据。和模块一样,类也支持" " Python 动态特性:在运行时创建,创建后还可以修改。" #: ../../tutorial/classes.rst:23 msgid "" "In C++ terminology, normally class members (including the data members) are " "*public* (except see below :ref:`tut-private`), and all member functions are" " *virtual*. As in Modula-3, there are no shorthands for referencing the " "object's members from its methods: the method function is declared with an " "explicit first argument representing the object, which is provided " "implicitly by the call. As in Smalltalk, classes themselves are objects. " "This provides semantics for importing and renaming. Unlike C++ and " "Modula-3, built-in types can be used as base classes for extension by the " "user. Also, like in C++, most built-in operators with special syntax " "(arithmetic operators, subscripting etc.) can be redefined for class " "instances." msgstr "" "如果用 C++ 术语来描述的话,类成员(包括数据成员)通常为 *public* (例外的情况见下文 :ref:`tut-" "private`),所有成员函数都为 *virtual* 。与 Modula-3 " "中一样,没有用于从对象的方法中引用本对象成员的简写形式:方法函数在声明时,有一个显式的第一个参数代表本对象,该参数由方法调用隐式提供。与在 " "Smalltalk 中一样,Python 的类也是对象,这为导入和重命名提供了语义支持。与 C++ 和 Modula-3 不同,Python " "的内置类型可以用作基类,供用户扩展。此外,与 C++ 一样,具有特殊语法的内置运算符(算术运算符、下标等)都可以为类实例重新定义。" #: ../../tutorial/classes.rst:34 msgid "" "(Lacking universally accepted terminology to talk about classes, I will make" " occasional use of Smalltalk and C++ terms. I would use Modula-3 terms, " "since its object-oriented semantics are closer to those of Python than C++, " "but I expect that few readers have heard of it.)" msgstr "" "由于缺乏关于类的公认术语,本章中偶尔会使用 Smalltalk 和 C++ 的术语。本章还会使用 Modula-3 的术语,Modula-3 " "的面向对象语义比 C++ 更接近 Python,但估计听说过这门语言的读者很少。" #: ../../tutorial/classes.rst:43 msgid "A Word About Names and Objects" msgstr "名称和对象" #: ../../tutorial/classes.rst:45 msgid "" "Objects have individuality, and multiple names (in multiple scopes) can be " "bound to the same object. This is known as aliasing in other languages. " "This is usually not appreciated on a first glance at Python, and can be " "safely ignored when dealing with immutable basic types (numbers, strings, " "tuples). However, aliasing has a possibly surprising effect on the " "semantics of Python code involving mutable objects such as lists, " "dictionaries, and most other types. This is usually used to the benefit of " "the program, since aliases behave like pointers in some respects. For " "example, passing an object is cheap since only a pointer is passed by the " "implementation; and if a function modifies an object passed as an argument, " "the caller will see the change --- this eliminates the need for two " "different argument passing mechanisms as in Pascal." msgstr "" "对象之间相互独立,多个名称(甚至是多个作用域内的多个名称)可以绑定到同一对象。这在其他语言中通常被称为别名。Python " "初学者通常不容易理解这个概念,处理数字、字符串、元组等不可变基本类型时,可以不必理会。但是,对于涉及可变对象(如列表、字典,以及大多数其他类型)的 " "Python " "代码的语义,别名可能会产生意料之外的效果。这样做,通常是为了让程序受益,因为别名在某些方面就像指针。例如,传递对象的代价很小,因为实现只传递一个指针;如果函数修改了作为参数传递的对象,调用者就可以看到更改——无需像" " Pascal 那样用两个不同的机制来传参。" #: ../../tutorial/classes.rst:61 msgid "Python Scopes and Namespaces" msgstr "Python 作用域和命名空间" #: ../../tutorial/classes.rst:63 msgid "" "Before introducing classes, I first have to tell you something about " "Python's scope rules. Class definitions play some neat tricks with " "namespaces, and you need to know how scopes and namespaces work to fully " "understand what's going on. Incidentally, knowledge about this subject is " "useful for any advanced Python programmer." msgstr "" "在介绍类前,首先要介绍 Python " "的作用域规则。类定义对命名空间有一些巧妙的技巧,了解作用域和命名空间的工作机制有利于加强对类的理解。并且,即便对于高级 Python " "程序员,这方面的知识也很有用。" #: ../../tutorial/classes.rst:69 msgid "Let's begin with some definitions." msgstr "接下来,我们先了解一些定义。" #: ../../tutorial/classes.rst:71 msgid "" "A *namespace* is a mapping from names to objects. Most namespaces are " "currently implemented as Python dictionaries, but that's normally not " "noticeable in any way (except for performance), and it may change in the " "future. Examples of namespaces are: the set of built-in names (containing " "functions such as :func:`abs`, and built-in exception names); the global " "names in a module; and the local names in a function invocation. In a sense" " the set of attributes of an object also form a namespace. The important " "thing to know about namespaces is that there is absolutely no relation " "between names in different namespaces; for instance, two different modules " "may both define a function ``maximize`` without confusion --- users of the " "modules must prefix it with the module name." msgstr "" "*namespace* (命名空间)是从名称到对象的映射。现在,大多数命名空间都使用 Python " "字典实现,但除非涉及到性能优化,我们一般不会关注这方面的事情,而且将来也可能会改变这种方式。命名空间的例子有:内置名称集合(包括 :func:`abs`" " " "函数以及内置异常的名称等);一个模块的全局名称;一个函数调用中的局部名称。对象的属性集合也是命名空间的一种形式。关于命名空间的一个重要知识点是,不同命名空间中的名称之间绝对没有关系;例如,两个不同的模块都可以定义" " ``maximize`` 函数,且不会造成混淆。用户使用函数时必须要在函数名前面加上模块名。" #: ../../tutorial/classes.rst:82 msgid "" "By the way, I use the word *attribute* for any name following a dot --- for " "example, in the expression ``z.real``, ``real`` is an attribute of the " "object ``z``. Strictly speaking, references to names in modules are " "attribute references: in the expression ``modname.funcname``, ``modname`` is" " a module object and ``funcname`` is an attribute of it. In this case there" " happens to be a straightforward mapping between the module's attributes and" " the global names defined in the module: they share the same namespace! " "[#]_" msgstr "" "点号之后的名称是 **属性**。例如,表达式 ``z.real`` 中,``real`` 是对象 ``z`` " "的属性。严格来说,对模块中名称的引用是属性引用:表达式 ``modname.funcname`` 中,``modname`` " "是模块对象,``funcname`` 是模块的属性。模块属性和模块中定义的全局名称之间存在直接的映射:它们共享相同的命名空间! [#]_" #: ../../tutorial/classes.rst:90 msgid "" "Attributes may be read-only or writable. In the latter case, assignment to " "attributes is possible. Module attributes are writable: you can write " "``modname.the_answer = 42``. Writable attributes may also be deleted with " "the :keyword:`del` statement. For example, ``del modname.the_answer`` will " "remove the attribute :attr:`the_answer` from the object named by " "``modname``." msgstr "" "属性可以是只读或者可写的。如果可写,则可对属性赋值。模块属性是可写时,可以使用 ``modname.the_answer = 42`` " "。:keyword:`del` 语句可以删除可写属性。例如, ``del modname.the_answer`` 会删除 ``modname`` " "对象中的 :attr:`the_answer` 属性。" #: ../../tutorial/classes.rst:96 msgid "" "Namespaces are created at different moments and have different lifetimes. " "The namespace containing the built-in names is created when the Python " "interpreter starts up, and is never deleted. The global namespace for a " "module is created when the module definition is read in; normally, module " "namespaces also last until the interpreter quits. The statements executed " "by the top-level invocation of the interpreter, either read from a script " "file or interactively, are considered part of a module called " ":mod:`__main__`, so they have their own global namespace. (The built-in " "names actually also live in a module; this is called :mod:`builtins`.)" msgstr "" "命名空间是在不同时刻创建的,且拥有不同的生命周期。内置名称的命名空间是在 Python " "解释器启动时创建的,永远不会被删除。模块的全局命名空间在读取模块定义时创建;通常,模块的命名空间也会持续到解释器退出。从脚本文件读取或交互式读取的,由解释器顶层调用执行的语句是" " :mod:`__main__` 模块调用的一部分,也拥有自己的全局命名空间。内置名称实际上也在模块里,即 :mod:`builtins` 。" #: ../../tutorial/classes.rst:106 msgid "" "The local namespace for a function is created when the function is called, " "and deleted when the function returns or raises an exception that is not " "handled within the function. (Actually, forgetting would be a better way to" " describe what actually happens.) Of course, recursive invocations each " "have their own local namespace." msgstr "" "函数的局部命名空间在函数被调用时被创建,并在函数返回或抛出未在函数内被处理的异常时,被删除。(实际上,用“遗忘”来描述实际发生的情况会更好一些。)当然,每次递归调用都有自己的局部命名空间。" #: ../../tutorial/classes.rst:112 msgid "" "A *scope* is a textual region of a Python program where a namespace is " "directly accessible. \"Directly accessible\" here means that an unqualified" " reference to a name attempts to find the name in the namespace." msgstr "" "一个命名空间的 *作用域* 是 Python " "代码中的一段文本区域,从这个区域可直接访问该命名空间。“可直接访问”的意思是,该文本区域内的名称在被非限定引用时,查找名称的范围,是包括该命名空间在内的。" #: ../../tutorial/classes.rst:116 msgid "" "Although scopes are determined statically, they are used dynamically. At any" " time during execution, there are 3 or 4 nested scopes whose namespaces are " "directly accessible:" msgstr "作用域虽然是被静态确定的,但会被动态使用。执行期间的任何时刻,都会有 3 或 4 个“命名空间可直接访问”的嵌套作用域:" #: ../../tutorial/classes.rst:120 msgid "the innermost scope, which is searched first, contains the local names" msgstr "最内层作用域,包含局部名称,并首先在其中进行搜索" #: ../../tutorial/classes.rst:121 msgid "" "the scopes of any enclosing functions, which are searched starting with the " "nearest enclosing scope, contain non-local, but also non-global names" msgstr "那些外层闭包函数的作用域,包含“非局部、非全局”的名称,从最靠内层的那个作用域开始,逐层向外搜索。" #: ../../tutorial/classes.rst:123 msgid "the next-to-last scope contains the current module's global names" msgstr "倒数第二层作用域,包含当前模块的全局名称" #: ../../tutorial/classes.rst:124 msgid "" "the outermost scope (searched last) is the namespace containing built-in " "names" msgstr "最外层(最后搜索)的作用域,是内置名称的命名空间" #: ../../tutorial/classes.rst:126 msgid "" "If a name is declared global, then all references and assignments go " "directly to the next-to-last scope containing the module's global names. To" " rebind variables found outside of the innermost scope, the " ":keyword:`nonlocal` statement can be used; if not declared nonlocal, those " "variables are read-only (an attempt to write to such a variable will simply " "create a *new* local variable in the innermost scope, leaving the " "identically named outer variable unchanged)." msgstr "" "如果一个名称被声明为全局,则所有引用和赋值都将直接指向“倒数第二层作用域”,即包含模块的全局名称的作用域。 " "要重新绑定在最内层作用域以外找到的变量,可以使用 :keyword:`nonlocal` 语句;如果未使用 nonlocal " "声明,这些变量将为只读(尝试写入这样的变量将在最内层作用域中创建一个 *新的* 局部变量,而使得同名的外部变量保持不变)。" #: ../../tutorial/classes.rst:133 msgid "" "Usually, the local scope references the local names of the (textually) " "current function. Outside functions, the local scope references the same " "namespace as the global scope: the module's namespace. Class definitions " "place yet another namespace in the local scope." msgstr "" "通常,当前局部作用域将(按字面文本)引用当前函数的局部名称。在函数之外,局部作用域引用与全局作用域一致的命名空间:模块的命名空间。 " "类定义在局部命名空间内再放置另一个命名空间。" #: ../../tutorial/classes.rst:138 msgid "" "It is important to realize that scopes are determined textually: the global " "scope of a function defined in a module is that module's namespace, no " "matter from where or by what alias the function is called. On the other " "hand, the actual search for names is done dynamically, at run time --- " "however, the language definition is evolving towards static name resolution," " at \"compile\" time, so don't rely on dynamic name resolution! (In fact, " "local variables are already determined statically.)" msgstr "" "划重点,作用域是按字面文本确定的:模块内定义的函数的全局作用域就是该模块的命名空间,无论该函数从什么地方或以什么别名被调用。另一方面,实际的名称搜索是在运行时动态完成的。但是,Python" " 正在朝着“编译时静态名称解析”的方向发展,因此不要过于依赖动态名称解析!(局部变量已经是被静态确定了。)" #: ../../tutorial/classes.rst:146 msgid "" "A special quirk of Python is that -- if no :keyword:`global` or " ":keyword:`nonlocal` statement is in effect -- assignments to names always go" " into the innermost scope. Assignments do not copy data --- they just bind " "names to objects. The same is true for deletions: the statement ``del x`` " "removes the binding of ``x`` from the namespace referenced by the local " "scope. In fact, all operations that introduce new names use the local " "scope: in particular, :keyword:`import` statements and function definitions " "bind the module or function name in the local scope." msgstr "" "Python 有一个特殊规定。如果不存在生效的 :keyword:`global` 或 :keyword:`nonlocal` " "语句,则对名称的赋值总是会进入最内层作用域。赋值不会复制数据,只是将名称绑定到对象。删除也是如此:语句 ``del x`` " "从局部作用域引用的命名空间中移除对 ``x`` 的绑定。所有引入新名称的操作都是使用局部作用域:尤其是 :keyword:`import` " "语句和函数定义会在局部作用域中绑定模块或函数名称。" #: ../../tutorial/classes.rst:154 msgid "" "The :keyword:`global` statement can be used to indicate that particular " "variables live in the global scope and should be rebound there; the " ":keyword:`nonlocal` statement indicates that particular variables live in an" " enclosing scope and should be rebound there." msgstr "" ":keyword:`global` 语句用于表明特定变量在全局作用域里,并应在全局作用域中重新绑定;:keyword:`nonlocal` " "语句表明特定变量在外层作用域中,并应在外层作用域中重新绑定。" #: ../../tutorial/classes.rst:162 msgid "Scopes and Namespaces Example" msgstr "作用域和命名空间示例" #: ../../tutorial/classes.rst:164 msgid "" "This is an example demonstrating how to reference the different scopes and " "namespaces, and how :keyword:`global` and :keyword:`nonlocal` affect " "variable binding::" msgstr "" "下例演示了如何引用不同作用域和名称空间,以及 :keyword:`global` 和 :keyword:`nonlocal` 对变量绑定的影响:" #: ../../tutorial/classes.rst:191 msgid "The output of the example code is:" msgstr "示例代码的输出是:" #: ../../tutorial/classes.rst:200 msgid "" "Note how the *local* assignment (which is default) didn't change " "*scope_test*\\'s binding of *spam*. The :keyword:`nonlocal` assignment " "changed *scope_test*\\'s binding of *spam*, and the :keyword:`global` " "assignment changed the module-level binding." msgstr "" "注意,**局部** 赋值(这是默认状态)不会改变 *scope_test* 对 *spam* 的绑定。 :keyword:`nonlocal` " "赋值会改变 *scope_test* 对 *spam* 的绑定,而 :keyword:`global` 赋值会改变模块层级的绑定。" #: ../../tutorial/classes.rst:205 msgid "" "You can also see that there was no previous binding for *spam* before the " ":keyword:`global` assignment." msgstr "而且,:keyword:`global` 赋值前没有 *spam* 的绑定。" #: ../../tutorial/classes.rst:212 msgid "A First Look at Classes" msgstr "初探类" #: ../../tutorial/classes.rst:214 msgid "" "Classes introduce a little bit of new syntax, three new object types, and " "some new semantics." msgstr "类引入了一点新语法,三种新的对象类型和一些新语义。" #: ../../tutorial/classes.rst:221 msgid "Class Definition Syntax" msgstr "类定义语法" #: ../../tutorial/classes.rst:223 msgid "The simplest form of class definition looks like this::" msgstr "最简单的类定义形式如下:" #: ../../tutorial/classes.rst:232 msgid "" "Class definitions, like function definitions (:keyword:`def` statements) " "must be executed before they have any effect. (You could conceivably place " "a class definition in a branch of an :keyword:`if` statement, or inside a " "function.)" msgstr "" "与函数定义 (:keyword:`def` 语句) 一样,类定义必须先执行才能生效。把类定义放在 :keyword:`if` " "语句的分支里或函数内部试试。" #: ../../tutorial/classes.rst:236 msgid "" "In practice, the statements inside a class definition will usually be " "function definitions, but other statements are allowed, and sometimes useful" " --- we'll come back to this later. The function definitions inside a class" " normally have a peculiar form of argument list, dictated by the calling " "conventions for methods --- again, this is explained later." msgstr "" "在实践中,类定义内的语句通常都是函数定义,但也可以是其他语句。这部分内容稍后再讨论。类里的函数定义一般是特殊的参数列表,这是由方法调用的约定规范所指明的" " --- 同样,稍后再解释。" #: ../../tutorial/classes.rst:242 msgid "" "When a class definition is entered, a new namespace is created, and used as " "the local scope --- thus, all assignments to local variables go into this " "new namespace. In particular, function definitions bind the name of the new" " function here." msgstr "" "当进入类定义时,将创建一个新的命名空间,并将其用作局部作用域 --- 因此,所有对局部变量的赋值都是在这个新命名空间之内。 " "特别的,函数定义会绑定到这里的新函数名称。" #: ../../tutorial/classes.rst:247 msgid "" "When a class definition is left normally (via the end), a *class object* is " "created. This is basically a wrapper around the contents of the namespace " "created by the class definition; we'll learn more about class objects in the" " next section. The original local scope (the one in effect just before the " "class definition was entered) is reinstated, and the class object is bound " "here to the class name given in the class definition header " "(:class:`ClassName` in the example)." msgstr "" "当(从结尾处)正常离开类定义时,将创建一个 *类对象*。 " "这基本上是一个包围在类定义所创建命名空间内容周围的包装器;我们将在下一节了解有关类对象的更多信息。 " "原始的(在进入类定义之前起作用的)局部作用域将重新生效,类对象将在这里被绑定到类定义头所给出的类名称 (在这个示例中为 " ":class:`ClassName`)。" #: ../../tutorial/classes.rst:259 msgid "Class Objects" msgstr "Class 对象" #: ../../tutorial/classes.rst:261 msgid "" "Class objects support two kinds of operations: attribute references and " "instantiation." msgstr "类对象支持两种操作:属性引用和实例化。" #: ../../tutorial/classes.rst:264 msgid "" "*Attribute references* use the standard syntax used for all attribute " "references in Python: ``obj.name``. Valid attribute names are all the names" " that were in the class's namespace when the class object was created. So, " "if the class definition looked like this::" msgstr "" "*属性引用* 使用 Python 中所有属性引用所使用的标准语法: ``obj.name``。 " "有效的属性名称是类对象被创建时存在于类命名空间中的所有名称。 因此,如果类定义是这样的::" #: ../../tutorial/classes.rst:276 msgid "" "then ``MyClass.i`` and ``MyClass.f`` are valid attribute references, " "returning an integer and a function object, respectively. Class attributes " "can also be assigned to, so you can change the value of ``MyClass.i`` by " "assignment. :attr:`__doc__` is also a valid attribute, returning the " "docstring belonging to the class: ``\"A simple example class\"``." msgstr "" "那么 ``MyClass.i`` 和 ``MyClass.f`` 就是有效的属性引用,将分别返回一个整数和一个函数对象。 " "类属性也可以被赋值,因此可以通过赋值来更改 ``MyClass.i`` 的值。 :attr:`__doc__` " "也是一个有效的属性,将返回所属类的文档字符串: ``\"A simple example class\"``。" #: ../../tutorial/classes.rst:282 msgid "" "Class *instantiation* uses function notation. Just pretend that the class " "object is a parameterless function that returns a new instance of the class." " For example (assuming the above class)::" msgstr "类的 *实例化* 使用函数表示法。 可以把类对象视为是返回该类的一个新实例的不带参数的函数。 举例来说(假设使用上述的类)::" #: ../../tutorial/classes.rst:288 msgid "" "creates a new *instance* of the class and assigns this object to the local " "variable ``x``." msgstr "创建类的新 *实例* 并将此对象分配给局部变量 ``x``。" #: ../../tutorial/classes.rst:291 msgid "" "The instantiation operation (\"calling\" a class object) creates an empty " "object. Many classes like to create objects with instances customized to a " "specific initial state. Therefore a class may define a special method named " ":meth:`__init__`, like this::" msgstr "" "实例化操作(“调用”类对象)会创建一个空对象。 许多类喜欢创建带有特定初始状态的自定义实例。 为此类定义可能包含一个名为 " ":meth:`__init__` 的特殊方法,就像这样::" #: ../../tutorial/classes.rst:299 msgid "" "When a class defines an :meth:`__init__` method, class instantiation " "automatically invokes :meth:`__init__` for the newly created class instance." " So in this example, a new, initialized instance can be obtained by::" msgstr "" "当一个类定义了 :meth:`__init__` 方法时,类的实例化操作会自动为新创建的类实例发起调用 :meth:`__init__`。 " "因此在这个例子中,可以通过以下语句获得一个新的已初始化实例::" #: ../../tutorial/classes.rst:305 msgid "" "Of course, the :meth:`__init__` method may have arguments for greater " "flexibility. In that case, arguments given to the class instantiation " "operator are passed on to :meth:`__init__`. For example, ::" msgstr "" "当然,:meth:`__init__` 方法还可以有额外参数以实现更高灵活性。 在这种情况下,提供给类实例化运算符的参数将被传递给 " ":meth:`__init__`。 例如,::" #: ../../tutorial/classes.rst:322 msgid "Instance Objects" msgstr "实例对象" #: ../../tutorial/classes.rst:324 msgid "" "Now what can we do with instance objects? The only operations understood by" " instance objects are attribute references. There are two kinds of valid " "attribute names: data attributes and methods." msgstr "现在我们能用实例对象做什么? 实例对象所能理解的唯一操作是属性引用。 有两种有效的属性名称:数据属性和方法。" #: ../../tutorial/classes.rst:328 msgid "" "*Data attributes* correspond to \"instance variables\" in Smalltalk, and to " "\"data members\" in C++. Data attributes need not be declared; like local " "variables, they spring into existence when they are first assigned to. For " "example, if ``x`` is the instance of :class:`MyClass` created above, the " "following piece of code will print the value ``16``, without leaving a " "trace::" msgstr "" #: ../../tutorial/classes.rst:340 msgid "" "The other kind of instance attribute reference is a *method*. A method is a " "function that \"belongs to\" an object. (In Python, the term method is not " "unique to class instances: other object types can have methods as well. For" " example, list objects have methods called append, insert, remove, sort, and" " so on. However, in the following discussion, we'll use the term method " "exclusively to mean methods of class instance objects, unless explicitly " "stated otherwise.)" msgstr "" "另一类实例属性引用称为 *方法*。 方法是“从属于”对象的函数。 (在 Python 中,方法这个术语并不是类实例所特有的:其他对象也可以有方法。 " "例如,列表对象具有 append, insert, remove, sort 等方法。 " "然而,在以下讨论中,我们使用方法一词将专指类实例对象的方法,除非另外显式地说明。)" #: ../../tutorial/classes.rst:349 msgid "" "Valid method names of an instance object depend on its class. By " "definition, all attributes of a class that are function objects define " "corresponding methods of its instances. So in our example, ``x.f`` is a " "valid method reference, since ``MyClass.f`` is a function, but ``x.i`` is " "not, since ``MyClass.i`` is not. But ``x.f`` is not the same thing as " "``MyClass.f`` --- it is a *method object*, not a function object." msgstr "" "实例对象的有效方法名称依赖于其所属的类。 根据定义,一个类中所有是函数对象的属性都是定义了其实例的相应方法。 因此在我们的示例中,``x.f`` " "是有效的方法引用,因为 ``MyClass.f`` 是一个函数,而 ``x.i`` 不是方法,因为 ``MyClass.i`` 不是函数。 但是 " "``x.f`` 与 ``MyClass.f`` 并不是一回事 --- 它是一个 *方法对象*,不是函数对象。" #: ../../tutorial/classes.rst:360 msgid "Method Objects" msgstr "方法对象" #: ../../tutorial/classes.rst:362 msgid "Usually, a method is called right after it is bound::" msgstr "通常,方法在绑定后立即被调用::" #: ../../tutorial/classes.rst:366 msgid "" "In the :class:`MyClass` example, this will return the string ``'hello " "world'``. However, it is not necessary to call a method right away: ``x.f`` " "is a method object, and can be stored away and called at a later time. For " "example::" msgstr "" "在 :class:`MyClass` 示例中,这将返回字符串 ``'hello world'``。 但是,立即调用一个方法并不是必须的: ``x.f``" " 是一个方法对象,它可以被保存起来以后再调用。 例如::" #: ../../tutorial/classes.rst:374 msgid "will continue to print ``hello world`` until the end of time." msgstr "将持续打印 ``hello world``,直到结束。" #: ../../tutorial/classes.rst:376 msgid "" "What exactly happens when a method is called? You may have noticed that " "``x.f()`` was called without an argument above, even though the function " "definition for :meth:`f` specified an argument. What happened to the " "argument? Surely Python raises an exception when a function that requires an" " argument is called without any --- even if the argument isn't actually " "used..." msgstr "" "当一个方法被调用时到底发生了什么? 你可能已经注意到上面调用 ``x.f()`` 时并没有带参数,虽然 :meth:`f` 的函数定义指定了一个参数。 " "这个参数发生了什么事? 当不带参数地调用一个需要参数的函数时 Python 肯定会引发异常 --- 即使参数实际未被使用..." #: ../../tutorial/classes.rst:382 msgid "" "Actually, you may have guessed the answer: the special thing about methods " "is that the instance object is passed as the first argument of the function." " In our example, the call ``x.f()`` is exactly equivalent to " "``MyClass.f(x)``. In general, calling a method with a list of *n* arguments" " is equivalent to calling the corresponding function with an argument list " "that is created by inserting the method's instance object before the first " "argument." msgstr "" "实际上,你可能已经猜到了答案:方法的特殊之处就在于实例对象会作为函数的第一个参数被传入。 在我们的示例中,调用 ``x.f()`` 其实就相当于 " "``MyClass.f(x)``。 总之,调用一个具有 *n* " "个参数的方法就相当于调用再多一个参数的对应函数,这个参数值为方法所属实例对象,位置在其他参数之前。" #: ../../tutorial/classes.rst:389 msgid "" "If you still don't understand how methods work, a look at the implementation" " can perhaps clarify matters. When a non-data attribute of an instance is " "referenced, the instance's class is searched. If the name denotes a valid " "class attribute that is a function object, a method object is created by " "packing (pointers to) the instance object and the function object just found" " together in an abstract object: this is the method object. When the method" " object is called with an argument list, a new argument list is constructed " "from the instance object and the argument list, and the function object is " "called with this new argument list." msgstr "" "如果你仍然无法理解方法的运作原理,那么看了实现细节可能会弄清楚问题。当对实例对象进行属性引用时,如果该属性在实例中无法找到,将搜索实例所属的类。如果被引用的属性名称表示一个有效的类属性中的函数对象,会打包两者(实例对象和查找到的函数对象)的指针到一个抽象对象,这个抽象对象就是方法对象。当用参数列表调用方法对象时,将基于实例对象和参数列表构建一个新的参数列表,并用这个新参数列表调用相应的函数对象。" #: ../../tutorial/classes.rst:403 msgid "Class and Instance Variables" msgstr "类和实例变量" #: ../../tutorial/classes.rst:405 msgid "" "Generally speaking, instance variables are for data unique to each instance " "and class variables are for attributes and methods shared by all instances " "of the class::" msgstr "一般来说,实例变量用于每个实例的唯一数据,而类变量用于类的所有实例共享的属性和方法::" #: ../../tutorial/classes.rst:427 msgid "" "As discussed in :ref:`tut-object`, shared data can have possibly surprising " "effects with involving :term:`mutable` objects such as lists and " "dictionaries. For example, the *tricks* list in the following code should " "not be used as a class variable because just a single list would be shared " "by all *Dog* instances::" msgstr "" "正如 :ref:`tut-object` 中已讨论过的,共享数据可能在涉及 :term:`mutable` 对象例如列表和字典的时候导致令人惊讶的结果。" " 例如以下代码中的 *tricks* 列表不应该被用作类变量,因为所有的 *Dog* 实例将只共享一个单独的列表::" #: ../../tutorial/classes.rst:450 msgid "Correct design of the class should use an instance variable instead::" msgstr "正确的类设计应该使用实例变量::" #: ../../tutorial/classes.rst:474 msgid "Random Remarks" msgstr "补充说明" #: ../../tutorial/classes.rst:478 msgid "" "If the same attribute name occurs in both an instance and in a class, then " "attribute lookup prioritizes the instance::" msgstr "如果同样的属性名称同时出现在实例和类中,则属性查找会优先选择实例::" #: ../../tutorial/classes.rst:493 msgid "" "Data attributes may be referenced by methods as well as by ordinary users " "(\"clients\") of an object. In other words, classes are not usable to " "implement pure abstract data types. In fact, nothing in Python makes it " "possible to enforce data hiding --- it is all based upon convention. (On " "the other hand, the Python implementation, written in C, can completely hide" " implementation details and control access to an object if necessary; this " "can be used by extensions to Python written in C.)" msgstr "" "数据属性可以被方法以及一个对象的普通用户(“客户端”)所引用。 换句话说,类不能用于实现纯抽象数据类型。 实际上,在 Python " "中没有任何东西能强制隐藏数据 --- 它是完全基于约定的。 (而在另一方面,用 C 语言编写的 Python " "实现则可以完全隐藏实现细节,并在必要时控制对象的访问;此特性可以通过用 C 编写 Python 扩展来使用。)" #: ../../tutorial/classes.rst:501 msgid "" "Clients should use data attributes with care --- clients may mess up " "invariants maintained by the methods by stamping on their data attributes. " "Note that clients may add data attributes of their own to an instance object" " without affecting the validity of the methods, as long as name conflicts " "are avoided --- again, a naming convention can save a lot of headaches here." msgstr "" "客户端应当谨慎地使用数据属性 --- 客户端可能通过直接操作数据属性的方式破坏由方法所维护的固定变量。 " "请注意客户端可以向一个实例对象添加他们自己的数据属性而不会影响方法的可用性,只要保证避免名称冲突 --- " "再次提醒,在此使用命名约定可以省去许多令人头痛的麻烦。" #: ../../tutorial/classes.rst:507 msgid "" "There is no shorthand for referencing data attributes (or other methods!) " "from within methods. I find that this actually increases the readability of" " methods: there is no chance of confusing local variables and instance " "variables when glancing through a method." msgstr "" "在方法内部引用数据属性(或其他方法!)并没有简便方式。 我发现这实际上提升了方法的可读性:当浏览一个方法代码时,不会存在混淆局部变量和实例变量的机会。" #: ../../tutorial/classes.rst:512 msgid "" "Often, the first argument of a method is called ``self``. This is nothing " "more than a convention: the name ``self`` has absolutely no special meaning " "to Python. Note, however, that by not following the convention your code " "may be less readable to other Python programmers, and it is also conceivable" " that a *class browser* program might be written that relies upon such a " "convention." msgstr "" "方法的第一个参数常常被命名为 ``self``。 这也不过就是一个约定: ``self`` 这一名称在 Python 中绝对没有特殊含义。 " "但是要注意,不遵循此约定会使得你的代码对其他 Python 程序员来说缺乏可读性,而且也可以想像一个 *类浏览器* 程序的编写可能会依赖于这样的约定。" #: ../../tutorial/classes.rst:518 msgid "" "Any function object that is a class attribute defines a method for instances" " of that class. It is not necessary that the function definition is " "textually enclosed in the class definition: assigning a function object to a" " local variable in the class is also ok. For example::" msgstr "" "任何一个作为类属性的函数都为该类的实例定义了一个相应方法。 函数定义的文本并非必须包含于类定义之内:将一个函数对象赋值给一个局部变量也是可以的。 " "例如::" #: ../../tutorial/classes.rst:535 msgid "" "Now ``f``, ``g`` and ``h`` are all attributes of class :class:`C` that refer" " to function objects, and consequently they are all methods of instances of " ":class:`C` --- ``h`` being exactly equivalent to ``g``. Note that this " "practice usually only serves to confuse the reader of a program." msgstr "" "现在 ``f``, ``g`` 和 ``h`` 都是 :class:`C` 类的引用函数对象的属性,因而它们就都是 :class:`C` 的实例的方法 " "--- 其中 ``h`` 完全等同于 ``g``。 但请注意,本示例的做法通常只会令程序的阅读者感到迷惑。" #: ../../tutorial/classes.rst:540 msgid "" "Methods may call other methods by using method attributes of the ``self`` " "argument::" msgstr "方法可以通过使用 ``self`` 参数的方法属性调用其他方法::" #: ../../tutorial/classes.rst:554 msgid "" "Methods may reference global names in the same way as ordinary functions. " "The global scope associated with a method is the module containing its " "definition. (A class is never used as a global scope.) While one rarely " "encounters a good reason for using global data in a method, there are many " "legitimate uses of the global scope: for one thing, functions and modules " "imported into the global scope can be used by methods, as well as functions " "and classes defined in it. Usually, the class containing the method is " "itself defined in this global scope, and in the next section we'll find some" " good reasons why a method would want to reference its own class." msgstr "" "方法可以通过与普通函数相同的方式引用全局名称。与方法相关联的全局作用域就是包含该方法的定义语句的模块。(类永远不会被用作全局作用域。)尽管一个人很少会有好的理由在方法中使用全局作用域中的数据,全局作用域依然存在许多合理的使用场景:举个例子,导入到全局作用域的函数和模块可以被方法所使用,定义在全局作用域中的函数和类也一样。通常,包含该方法的类本身就定义在全局作用域中,而在下一节中我们将会发现,为何有些时候方法需要引用其所属类。" #: ../../tutorial/classes.rst:564 msgid "" "Each value is an object, and therefore has a *class* (also called its " "*type*). It is stored as ``object.__class__``." msgstr "每个值都是一个对象,因此具有 *类* (也称为 *类型*),并存储为 ``object.__class__`` 。" #: ../../tutorial/classes.rst:571 msgid "Inheritance" msgstr "继承" #: ../../tutorial/classes.rst:573 msgid "" "Of course, a language feature would not be worthy of the name \"class\" " "without supporting inheritance. The syntax for a derived class definition " "looks like this::" msgstr "当然,如果不支持继承,语言特性就不值得称为“类”。派生类定义的语法如下所示::" #: ../../tutorial/classes.rst:584 msgid "" "The name :class:`BaseClassName` must be defined in a scope containing the " "derived class definition. In place of a base class name, other arbitrary " "expressions are also allowed. This can be useful, for example, when the " "base class is defined in another module::" msgstr "" "名称 :class:`BaseClassName` 必须定义于包含派生类定义的作用域中。 也允许用其他任意表达式代替基类名称所在的位置。 " "这有时也可能会用得上,例如,当基类定义在另一个模块中的时候::" #: ../../tutorial/classes.rst:591 msgid "" "Execution of a derived class definition proceeds the same as for a base " "class. When the class object is constructed, the base class is remembered. " "This is used for resolving attribute references: if a requested attribute is" " not found in the class, the search proceeds to look in the base class. " "This rule is applied recursively if the base class itself is derived from " "some other class." msgstr "" "派生类定义的执行过程与基类相同。 当构造类对象时,基类会被记住。 此信息将被用来解析属性引用:如果请求的属性在类中找不到,搜索将转往基类中进行查找。 " "如果基类本身也派生自其他某个类,则此规则将被递归地应用。" #: ../../tutorial/classes.rst:597 msgid "" "There's nothing special about instantiation of derived classes: " "``DerivedClassName()`` creates a new instance of the class. Method " "references are resolved as follows: the corresponding class attribute is " "searched, descending down the chain of base classes if necessary, and the " "method reference is valid if this yields a function object." msgstr "" "派生类的实例化没有任何特殊之处: ``DerivedClassName()`` 会创建该类的一个新实例。 " "方法引用将按以下方式解析:搜索相应的类属性,如有必要将按基类继承链逐步向下查找,如果产生了一个函数对象则方法引用就生效。" #: ../../tutorial/classes.rst:603 msgid "" "Derived classes may override methods of their base classes. Because methods" " have no special privileges when calling other methods of the same object, a" " method of a base class that calls another method defined in the same base " "class may end up calling a method of a derived class that overrides it. " "(For C++ programmers: all methods in Python are effectively ``virtual``.)" msgstr "" "派生类可能会重写其基类的方法。 " "因为方法在调用同一对象的其他方法时没有特殊权限,所以基类方法在尝试调用调用同一基类中定义的另一方法时,可能实际上调用是该基类的派生类中定义的方法。(对 " "C++ 程序员的提示:Python 中所有的方法实际上都是 ``virtual`` 方法。)" #: ../../tutorial/classes.rst:609 msgid "" "An overriding method in a derived class may in fact want to extend rather " "than simply replace the base class method of the same name. There is a " "simple way to call the base class method directly: just call " "``BaseClassName.methodname(self, arguments)``. This is occasionally useful " "to clients as well. (Note that this only works if the base class is " "accessible as ``BaseClassName`` in the global scope.)" msgstr "" "在派生类中的重写方法实际上可能想要扩展而非简单地替换同名的基类方法。 有一种方式可以简单地直接调用基类方法:即调用 " "``BaseClassName.methodname(self, arguments)``。 有时这对客户端来说也是有用的。 " "(请注意仅当此基类可在全局作用域中以 ``BaseClassName`` 的名称被访问时方可使用此方式。)" #: ../../tutorial/classes.rst:616 msgid "Python has two built-in functions that work with inheritance:" msgstr "Python有两个内置函数可被用于继承机制:" #: ../../tutorial/classes.rst:618 msgid "" "Use :func:`isinstance` to check an instance's type: ``isinstance(obj, int)``" " will be ``True`` only if ``obj.__class__`` is :class:`int` or some class " "derived from :class:`int`." msgstr "" "使用 :func:`isinstance` 来检查一个实例的类型: ``isinstance(obj, int)`` 仅会在 " "``obj.__class__`` 为 :class:`int` 或某个派生自 :class:`int` 的类时为 ``True``。" #: ../../tutorial/classes.rst:622 msgid "" "Use :func:`issubclass` to check class inheritance: ``issubclass(bool, int)``" " is ``True`` since :class:`bool` is a subclass of :class:`int`. However, " "``issubclass(float, int)`` is ``False`` since :class:`float` is not a " "subclass of :class:`int`." msgstr "" "使用 :func:`issubclass` 来检查类的继承关系: ``issubclass(bool, int)`` 为 ``True``,因为 " ":class:`bool` 是 :class:`int` 的子类。 但是,``issubclass(float, int)`` 为 " "``False``,因为 :class:`float` 不是 :class:`int` 的子类。" #: ../../tutorial/classes.rst:632 msgid "Multiple Inheritance" msgstr "多重继承" #: ../../tutorial/classes.rst:634 msgid "" "Python supports a form of multiple inheritance as well. A class definition " "with multiple base classes looks like this::" msgstr "Python 也支持一种多重继承。 带有多个基类的类定义语句如下所示::" #: ../../tutorial/classes.rst:644 msgid "" "For most purposes, in the simplest cases, you can think of the search for " "attributes inherited from a parent class as depth-first, left-to-right, not " "searching twice in the same class where there is an overlap in the " "hierarchy. Thus, if an attribute is not found in :class:`DerivedClassName`, " "it is searched for in :class:`Base1`, then (recursively) in the base classes" " of :class:`Base1`, and if it was not found there, it was searched for in " ":class:`Base2`, and so on." msgstr "" "对于多数应用来说,在最简单的情况下,你可以认为搜索从父类所继承属性的操作是深度优先、从左至右的,当层次结构中存在重叠时不会在同一个类中搜索两次。 " "因此,如果某一属性在 :class:`DerivedClassName` 中未找到,则会到 :class:`Base1` 中搜索它,然后(递归地)到 " ":class:`Base1` 的基类中搜索,如果在那里未找到,再到 :class:`Base2` 中搜索,依此类推。" #: ../../tutorial/classes.rst:651 msgid "" "In fact, it is slightly more complex than that; the method resolution order " "changes dynamically to support cooperative calls to :func:`super`. This " "approach is known in some other multiple-inheritance languages as call-next-" "method and is more powerful than the super call found in single-inheritance " "languages." msgstr "" "真实情况比这个更复杂一些;方法解析顺序会动态改变以支持对 :func:`super` 的协同调用。 " "这种方式在某些其他多重继承型语言中被称为后续方法调用,它比单继承型语言中的 super 调用更强大。" #: ../../tutorial/classes.rst:657 msgid "" "Dynamic ordering is necessary because all cases of multiple inheritance " "exhibit one or more diamond relationships (where at least one of the parent " "classes can be accessed through multiple paths from the bottommost class). " "For example, all classes inherit from :class:`object`, so any case of " "multiple inheritance provides more than one path to reach :class:`object`. " "To keep the base classes from being accessed more than once, the dynamic " "algorithm linearizes the search order in a way that preserves the left-to-" "right ordering specified in each class, that calls each parent only once, " "and that is monotonic (meaning that a class can be subclassed without " "affecting the precedence order of its parents). Taken together, these " "properties make it possible to design reliable and extensible classes with " "multiple inheritance. For more detail, see " "https://www.python.org/download/releases/2.3/mro/." msgstr "" "动态改变顺序是有必要的,因为所有多重继承的情况都会显示出一个或更多的菱形关联(即至少有一个父类可通过多条路径被最底层类所访问)。 例如,所有类都是继承自" " :class:`object`,因此任何多重继承的情况都提供了一条以上的路径可以通向 :class:`object`。 " "为了确保基类不会被访问一次以上,动态算法会用一种特殊方式将搜索顺序线性化, " "保留每个类所指定的从左至右的顺序,只调用每个父类一次,并且保持单调(即一个类可以被子类化而不影响其父类的优先顺序)。 " "总而言之,这些特性使得设计具有多重继承的可靠且可扩展的类成为可能。 要了解更多细节,请参阅 " "https://www.python.org/download/releases/2.3/mro/。" #: ../../tutorial/classes.rst:674 msgid "Private Variables" msgstr "私有变量" #: ../../tutorial/classes.rst:676 msgid "" "\"Private\" instance variables that cannot be accessed except from inside an" " object don't exist in Python. However, there is a convention that is " "followed by most Python code: a name prefixed with an underscore (e.g. " "``_spam``) should be treated as a non-public part of the API (whether it is " "a function, a method or a data member). It should be considered an " "implementation detail and subject to change without notice." msgstr "" "那种仅限从一个对象内部访问的“私有”实例变量在 Python 中并不存在。 但是,大多数 Python 代码都遵循这样一个约定:带有一个下划线的名称 " "(例如 ``_spam``) 应该被当作是 API 的非公有部分 (无论它是函数、方法或是数据成员)。 " "这应当被视为一个实现细节,可能不经通知即加以改变。" #: ../../tutorial/classes.rst:686 msgid "" "Since there is a valid use-case for class-private members (namely to avoid " "name clashes of names with names defined by subclasses), there is limited " "support for such a mechanism, called :dfn:`name mangling`. Any identifier " "of the form ``__spam`` (at least two leading underscores, at most one " "trailing underscore) is textually replaced with ``_classname__spam``, where " "``classname`` is the current class name with leading underscore(s) stripped." " This mangling is done without regard to the syntactic position of the " "identifier, as long as it occurs within the definition of a class." msgstr "" "由于存在对于类私有成员的有效使用场景(例如避免名称与子类所定义的名称相冲突),因此存在对此种机制的有限支持,称为 :dfn:`名称改写`。 任何形式为 " "``__spam`` 的标识符(至少带有两个前缀下划线,至多一个后缀下划线)的文本将被替换为 ``_classname__spam``,其中 " "``classname`` 为去除了前缀下划线的当前类名称。 这种改写不考虑标识符的句法位置,只要它出现在类定义内部就会进行。" #: ../../tutorial/classes.rst:695 msgid "" "Name mangling is helpful for letting subclasses override methods without " "breaking intraclass method calls. For example::" msgstr "名称改写有助于让子类重写方法而不破坏类内方法调用。例如::" #: ../../tutorial/classes.rst:717 msgid "" "The above example would work even if ``MappingSubclass`` were to introduce a" " ``__update`` identifier since it is replaced with ``_Mapping__update`` in " "the ``Mapping`` class and ``_MappingSubclass__update`` in the " "``MappingSubclass`` class respectively." msgstr "" "上面的示例即使在 ``MappingSubclass`` 引入了一个 ``__update`` 标识符的情况下也不会出错,因为它会在 " "``Mapping`` 类中被替换为 ``_Mapping__update`` 而在 ``MappingSubclass`` 类中被替换为 " "``_MappingSubclass__update``。" #: ../../tutorial/classes.rst:722 msgid "" "Note that the mangling rules are designed mostly to avoid accidents; it " "still is possible to access or modify a variable that is considered private." " This can even be useful in special circumstances, such as in the debugger." msgstr "请注意,改写规则的设计主要是为了避免意外冲突;访问或修改被视为私有的变量仍然是可能的。这在特殊情况下甚至会很有用,例如在调试器中。" #: ../../tutorial/classes.rst:726 msgid "" "Notice that code passed to ``exec()`` or ``eval()`` does not consider the " "classname of the invoking class to be the current class; this is similar to " "the effect of the ``global`` statement, the effect of which is likewise " "restricted to code that is byte-compiled together. The same restriction " "applies to ``getattr()``, ``setattr()`` and ``delattr()``, as well as when " "referencing ``__dict__`` directly." msgstr "" "请注意传递给 ``exec()`` 或 ``eval()`` 的代码不会将唤起类的类名视作当前类;这类似于 ``global`` " "语句的效果,因此这种效果仅限于同时经过字节码编译的代码。 同样的限制也适用于 ``getattr()``, ``setattr()`` 和 " "``delattr()``,以及对于 ``__dict__`` 的直接引用。" #: ../../tutorial/classes.rst:737 msgid "Odds and Ends" msgstr "杂项说明" #: ../../tutorial/classes.rst:739 msgid "" "Sometimes it is useful to have a data type similar to the Pascal \"record\" " "or C \"struct\", bundling together a few named data items. The idiomatic " "approach is to use :mod:`dataclasses` for this purpose::" msgstr "" "有时具有类似于 Pascal \"record\" 或 C \"struct\" 的数据类型是很有用的,将一些带名称的数据项捆绑在一起。 " "实现这一目标的理想方式是使用 :mod:`dataclasses`::" #: ../../tutorial/classes.rst:759 msgid "" "A piece of Python code that expects a particular abstract data type can " "often be passed a class that emulates the methods of that data type instead." " For instance, if you have a function that formats some data from a file " "object, you can define a class with methods :meth:`read` and " ":meth:`!readline` that get the data from a string buffer instead, and pass " "it as an argument." msgstr "" "一段需要特定抽象数据类型的 Python 代码往往可以被传入一个模拟了该数据类型的方法的类作为替代。 " "例如,如果你有一个基于文件对象来格式化某些数据的函数,你可以定义一个带有 :meth:`read` 和 :meth:`!readline` " "方法从字符串缓存获取数据的类,并将其作为参数传入。" #: ../../tutorial/classes.rst:770 msgid "" "Instance method objects have attributes, too: ``m.__self__`` is the instance" " object with the method :meth:`m`, and ``m.__func__`` is the function object" " corresponding to the method." msgstr "" "实例方法对象也具有属性: ``m.__self__`` 就是带有 :meth:`m` 方法的实例对象,而 ``m.__func__`` " "则是该方法所对应的函数对象。" #: ../../tutorial/classes.rst:778 msgid "Iterators" msgstr "迭代器" #: ../../tutorial/classes.rst:780 msgid "" "By now you have probably noticed that most container objects can be looped " "over using a :keyword:`for` statement::" msgstr "到目前为止,您可能已经注意到大多数容器对象都可以使用 :keyword:`for` 语句::" #: ../../tutorial/classes.rst:794 msgid "" "This style of access is clear, concise, and convenient. The use of " "iterators pervades and unifies Python. Behind the scenes, the " ":keyword:`for` statement calls :func:`iter` on the container object. The " "function returns an iterator object that defines the method " ":meth:`~iterator.__next__` which accesses elements in the container one at a" " time. When there are no more elements, :meth:`~iterator.__next__` raises a" " :exc:`StopIteration` exception which tells the :keyword:`!for` loop to " "terminate. You can call the :meth:`~iterator.__next__` method using the " ":func:`next` built-in function; this example shows how it all works::" msgstr "" "这种访问风格清晰、简洁又方便。 迭代器的使用非常普遍并使得 Python 成为一个统一的整体。 在幕后,:keyword:`for` " "语句会在容器对象上调用 :func:`iter`。 该函数返回一个定义了 :meth:`~iterator.__next__` " "方法的迭代器对象,此方法将逐一访问容器中的元素。 当元素用尽时,:meth:`~iterator.__next__` 将引发 " ":exc:`StopIteration` 异常来通知终止 :keyword:`!for` 循环。 你可以使用 :func:`next` 内置函数来调用 " ":meth:`~iterator.__next__` 方法;这个例子显示了它的运作方式::" #: ../../tutorial/classes.rst:819 msgid "" "Having seen the mechanics behind the iterator protocol, it is easy to add " "iterator behavior to your classes. Define an :meth:`__iter__` method which " "returns an object with a :meth:`~iterator.__next__` method. If the class " "defines :meth:`__next__`, then :meth:`__iter__` can just return ``self``::" msgstr "" "看过迭代器协议的幕后机制,给你的类添加迭代器行为就很容易了。 定义一个 :meth:`__iter__` 方法来返回一个带有 " ":meth:`~iterator.__next__` 方法的对象。 如果类已定义了 :meth:`__next__`,则 " ":meth:`__iter__` 可以简单地返回 ``self``::" #: ../../tutorial/classes.rst:856 msgid "Generators" msgstr "生成器" #: ../../tutorial/classes.rst:858 msgid "" ":term:`Generators ` are a simple and powerful tool for creating " "iterators. They are written like regular functions but use the " ":keyword:`yield` statement whenever they want to return data. Each time " ":func:`next` is called on it, the generator resumes where it left off (it " "remembers all the data values and which statement was last executed). An " "example shows that generators can be trivially easy to create::" msgstr "" ":term:`生成器 ` 是一个用于创建迭代器的简单而强大的工具。 它们的写法类似于标准的函数,但当它们要返回数据时会使用 " ":keyword:`yield` 语句。 每次在生成器上调用 :func:`next` " "时,它会从上次离开的位置恢复执行(它会记住上次执行语句时的所有数据值)。 一个显示如何非常容易地创建生成器的示例如下::" #: ../../tutorial/classes.rst:879 msgid "" "Anything that can be done with generators can also be done with class-based " "iterators as described in the previous section. What makes generators so " "compact is that the :meth:`__iter__` and :meth:`~generator.__next__` methods" " are created automatically." msgstr "" "可以用生成器来完成的操作同样可以用前一节所描述的基于类的迭代器来完成。 但生成器的写法更为紧凑,因为它会自动创建 :meth:`__iter__` 和 " ":meth:`~generator.__next__` 方法。" #: ../../tutorial/classes.rst:884 msgid "" "Another key feature is that the local variables and execution state are " "automatically saved between calls. This made the function easier to write " "and much more clear than an approach using instance variables like " "``self.index`` and ``self.data``." msgstr "" "另一个关键特性在于局部变量和执行状态会在每次调用之间自动保存。 这使得该函数相比使用 ``self.index`` 和 ``self.data`` " "这种实例变量的方式更易编写且更为清晰。" #: ../../tutorial/classes.rst:889 msgid "" "In addition to automatic method creation and saving program state, when " "generators terminate, they automatically raise :exc:`StopIteration`. In " "combination, these features make it easy to create iterators with no more " "effort than writing a regular function." msgstr "" "除了会自动创建方法和保存程序状态,当生成器终结时,它们还会自动引发 :exc:`StopIteration`。 " "这些特性结合在一起,使得创建迭代器能与编写常规函数一样容易。" #: ../../tutorial/classes.rst:898 msgid "Generator Expressions" msgstr "生成器表达式" #: ../../tutorial/classes.rst:900 msgid "" "Some simple generators can be coded succinctly as expressions using a syntax" " similar to list comprehensions but with parentheses instead of square " "brackets. These expressions are designed for situations where the generator " "is used right away by an enclosing function. Generator expressions are more" " compact but less versatile than full generator definitions and tend to be " "more memory friendly than equivalent list comprehensions." msgstr "" "某些简单的生成器可以写成简洁的表达式代码,所用语法类似列表推导式,但外层为圆括号而非方括号。 这种表达式被设计用于生成器将立即被外层函数所使用的情况。 " "生成器表达式相比完整的生成器更紧凑但较不灵活,相比等效的列表推导式则更为节省内存。" #: ../../tutorial/classes.rst:907 msgid "Examples::" msgstr "示例::" #: ../../tutorial/classes.rst:928 msgid "Footnotes" msgstr "备注" #: ../../tutorial/classes.rst:929 msgid "" "Except for one thing. Module objects have a secret read-only attribute " "called :attr:`~object.__dict__` which returns the dictionary used to " "implement the module's namespace; the name :attr:`~object.__dict__` is an " "attribute but not a global name. Obviously, using this violates the " "abstraction of namespace implementation, and should be restricted to things " "like post-mortem debuggers." msgstr "" "存在一个例外。 模块对象有一个秘密的只读属性 " ":attr:`~object.__dict__`,它返回用于实现模块命名空间的字典;:attr:`~object.__dict__` " "是属性但不是全局名称。 显然,使用这个将违反命名空间实现的抽象,应当仅被用于事后调试器之类的场合。"