# Copyright (C) 2001-2024, Python Software Foundation # This file is distributed under the same license as the Python package. # # Translators: # josix, 2018 # Steven Hsu , 2021 msgid "" msgstr "" "Project-Id-Version: Python 3.13\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-09-03 11:11+0800\n" "PO-Revision-Date: 2022-12-26 23:12+0800\n" "Last-Translator: Adrian Liaw \n" "Language-Team: Chinese - TAIWAN (https://github.com/python/python-docs-zh-" "tw)\n" "Language: zh_TW\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Poedit 3.2.2\n" "X-Poedit-Bookmarks: 0,26,52,77,102,-1,-1,-1,-1,-1\n" #: ../../tutorial/classes.rst:5 msgid "Classes" msgstr "Class(類別)" #: ../../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 "" "Class 提供了一種結合資料與功能的手段。建立一個 class 將會新增一個物件的\\ *型" "別 (type)*,並且允許建立該型別的新\\ *實例 (instance)*。每一個 class 實例可以" "擁有一些維持該實例狀態的屬性 (attribute)。Class 實例也可以有一些(由其 class " "所定義的)method(方法),用於修改該實例的狀態。" #: ../../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 的 class 機制為 class 增加了最少的新語法跟語意。他" "混合了 C++ 和 Modula-3 的 class 機制。Python 的 class 提供了所有物件導向程式" "設計 (Object Oriented Programming) 的標準特色:class 繼承機制允許多個 base " "class(基底類別),一個 derived class(衍生類別)可以覆寫 (override) 其 base " "class 的任何 method,且一個 method 可以用相同的名稱呼叫其 base class 的 " "method。物件可以包含任意數量及任意種類的資料。如同模組一樣,class 也具有 " "Python 的動態特性:他們在執行期 (runtime) 被建立,且可以在建立之後被修改。" #: ../../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++ 的術語中,class 成員(包含資料成員)通常都是\\ *公開*\\ 的(除了以下內" "容::ref:`tut-private`\\ ),而所有的成員函式都是\\ *虛擬*\\ 的。如同在 " "Modula-3 中一樣,Python 並沒有提供簡寫可以從物件的 method 裡參照其成員:" "method 函式與一個外顯的 (explicit)、第一個代表物件的引數被宣告,而此引數是在" "呼叫時隱性地 (implicitly) 被提供。如同在 Smalltak 中,class 都是物件,這為 " "import 及重新命名提供了語意。不像 C++ 和 Modula-3,Pyhon 內建的型別可以被使用" "者以 base class 用於其他擴充 (extension)。另外,如同在 C++ 中,大多數有著特別" "語法的內建運算子(算術運算子、下標等)都可以為了 class 實例而被重新定義。" #: ../../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 "" "(由於缺乏普遍能接受的術語來討論 class,我偶爾會使用 Smalltalk 和 C++ 的術" "語。我會使用 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 "" "物件有個體性 (individuality),且多個名稱(在多個作用域 (scope) )可以被連結到" "相同的物件。這在其他語言中被稱為別名 (aliasing)。初次接觸 Python 時通常不會注" "意這件事,而在處理不可變的基本型別(數值、字串、tuple)時,它也可以安全地被忽" "略。然而,別名在含有可變物件(如 list(串列)、dictionary(字典)、和大多數其" "他的型別)的 Python 程式碼語意中,可能會有意外的效果。這通常有利於程式,因為" "別名在某些方面表現得像指標 (pointer)。舉例來說,在實作時傳遞一個物件是便宜" "的,因為只有指標被傳遞;假如函式修改了一個作為引數傳遞的物件,呼叫函式者 " "(caller) 能夠見到這些改變——這消除了在 Pascal 中兩個相異引數傳遞機制的需求。" #: ../../tutorial/classes.rst:61 msgid "Python Scopes and Namespaces" msgstr "Python 作用域 (Scope) 及命名空間 (Namespace)" #: ../../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 "" "在介紹 class 之前,我必須先告訴你一些關於 Python 作用域的規則。Class " "definition(類別定義)以命名空間展現了一些俐落的技巧,而你需要了解作用域和命" "名空間的運作才能完整理解正在發生的事情。順帶一提,關於這個主題的知識對任何進" "階的 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 "" "*命名空間*\\ 是從名稱到物件的映射。大部分的命名空間現在都是以 Python 的 " "dictionary 被實作,但通常不會以任何方式被察覺(除了性能),且它可能會在未來改" "變。命名空間的例子有:內建名稱的集合(包含如 :func:`abs` 的函式,和內建的例外" "名稱);模組中的全域 (global) 名稱;和在函式調用中的區域 (local) 名稱。某種意" "義上,物件中的屬性集合也會形成一個命名空間。關於命名空間的重要一點是,不同命" "名空間中的名稱之間絕對沒有關係;舉例來說,兩個不一樣的模組都可以定義一個 " "``maximize`` 函式而不會混淆——模組的使用者必須為它加上前綴 (prefix) 模組名稱。" #: ../../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 "" "順帶一提,我使用\\ *屬性 (attribute)* 這個字,統稱句號 (dot) 後面的任何名稱——" "例如,運算式中的 ``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 直譯器啟動時,含有內" "建名稱的命名空間會被建立,並且永遠不會被刪除。當模組定義被讀入時,模組的全域" "命名空間會被建立;一般情況下,模組的命名空間也會持續到直譯器結束。被直譯器的" "頂層調用 (top-level invocation) 執行的陳述式,不論是從腳本檔案讀取的或是互動" "模式中的,會被視為一個稱為 :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 "" "函式的區域命名空間是在呼叫函式時建立的,而當函式返回,或引發了未在函式中處理" "的例外時,此命名空間將會被刪除。(實際上,忘記是描述實際發生的事情的更好方" "法。) 當然,每個遞迴調用 (recursive invocation) 都有自己的區域命名空間。" #: ../../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 程式中的一個文本區域 (textual region),在此區域,命名空" "間是可直接存取的。這裡的「可直接存取的」意思是,對一個名稱的非限定參照 " "(unqualified reference) 可以在命名空間內嘗試尋找該名稱。" #: ../../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 "" "任何外圍函式 (enclosing function) 的作用域,會從最近的外圍作用域開始搜尋,它" "包含了非區域 (non-local) 和非全域 (non-global) 的名稱" #: ../../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 "" "通常,區域作用域會參照(文本的)當前函式的區域名稱。在函式外部,區域作用域與" "全域作用域參照相同的命名空間:模組的命名空間。然而,Class definition 會在區域" "作用域中放置另一個命名空間。" #: ../../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 "" "務必要了解,作用域是按文本被決定的:在模組中定義的函式,其全域作用域便是該模" "組的命名空間,無論函式是從何處或以什麼別名被呼叫。另一方面,對名稱的實際搜尋" "是在執行時期 (run time) 動態完成的——但是,語言定義的發展,正朝向在「編譯」時" "期 (compile time) 的靜態名稱解析 (static name resolution),所以不要太依賴動態" "名稱解析 (dynamic name resolution)! (事實上,局部變數已經是靜態地被決定。)" #: ../../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` " "陳述式的效果——名稱的賦值 (assignment) 都會指向最內層作用域。賦值不會複製資料" "——它們只會把名稱連結至物件。刪除也是一樣:陳述式 ``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:168 msgid "" "def scope_test():\n" " def do_local():\n" " spam = \"local spam\"\n" "\n" " def do_nonlocal():\n" " nonlocal spam\n" " spam = \"nonlocal spam\"\n" "\n" " def do_global():\n" " global spam\n" " spam = \"global spam\"\n" "\n" " spam = \"test spam\"\n" " do_local()\n" " print(\"After local assignment:\", spam)\n" " do_nonlocal()\n" " print(\"After nonlocal assignment:\", spam)\n" " do_global()\n" " print(\"After global assignment:\", spam)\n" "\n" "scope_test()\n" "print(\"In global scope:\", spam)" msgstr "" #: ../../tutorial/classes.rst:191 msgid "The output of the example code is:" msgstr "範例程式碼的輸出是:" #: ../../tutorial/classes.rst:193 msgid "" "After local assignment: test spam\n" "After nonlocal assignment: nonlocal spam\n" "After global assignment: nonlocal spam\n" "In global scope: global spam" 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 "初見 class" #: ../../tutorial/classes.rst:214 msgid "" "Classes introduce a little bit of new syntax, three new object types, and " "some new semantics." msgstr "Class 採用一些新的語法,三個新的物件型別,以及一些新的語意。" #: ../../tutorial/classes.rst:221 msgid "Class Definition Syntax" msgstr "Class definition(類別定義)語法" #: ../../tutorial/classes.rst:223 msgid "The simplest form of class definition looks like this::" msgstr "Class definition 最簡單的形式如下: ::" #: ../../tutorial/classes.rst:225 msgid "" "class ClassName:\n" " \n" " .\n" " .\n" " .\n" " " msgstr "" "class ClassName:\n" " \n" " .\n" " .\n" " .\n" " " #: ../../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 "" "Class definition,如同函式定義(\\ :keyword:`def` 陳述式),必須在它們有任何" "效果前先執行。(你可以想像把 class definition 放在一個 :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 "" "在實作時,class definition 內的陳述式通常會是函式定義,但其他陳述式也是允許" "的,有時很有用——我們稍後會回到這裡。Class 中的函式定義通常會有一個獨特的引數" "列表形式,取決於 method 的呼叫慣例——再一次地,這將會在稍後解釋。" #: ../../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 "" "當進入 class definition,一個新的命名空間將會被建立,並且作為區域作用域——因" "此,所有區域變數的賦值將進入這個新的命名空間。特別是,函式定義會在這裡連結新" "函式的名稱。" #: ../../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 definition 時,一個 *class 物件*\\ 會被建立。基" "本上這是一個包裝器 (wrapper),裝著 class definition 建立的命名空間內容;我們" "將在下一節中更加了解 class 物件。原始的區域作用域(在進入 class definition 之" "前已生效的作用域)會恢復,在此 class 物件會被連結到 class definition 標頭中給" "出的 class 名稱(在範例中為 :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 "" "Class 物件支援兩種運算:屬性參照 (attribute reference) 和實例化 " "(instantiation)。" #: ../../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``。有效的屬性名" "稱是 class 物件被建立時,class 的命名空間中所有的名稱。所以,如果 class " "definition 看起來像這樣: ::" #: ../../tutorial/classes.rst:269 msgid "" "class MyClass:\n" " \"\"\"A simple example class\"\"\"\n" " i = 12345\n" "\n" " def f(self):\n" " return 'hello world'" msgstr "" "class MyClass:\n" " \"\"\"一個簡單的類別範例\"\"\"\n" " i = 12345\n" "\n" " def f(self):\n" " return 'hello world'" #: ../../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`` 都是有效的屬性參照,會分別回傳一個整數和" "一個函式物件。Class 屬性也可以被指派 (assign),所以你可以透過賦值改變 " "``MyClass.i`` 的值。:attr:`!__doc__` 也是一個有效的屬性,會回傳屬於該 class " "的說明字串 (docstring):``\"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 "" "Class *實例化*\\ 使用了函式記法 (function notation)。就好像 class 物件是一個" "沒有參數的函式,它回傳一個新的 class 實例。例如(假設是上述的 class): ::" #: ../../tutorial/classes.rst:286 ../../tutorial/classes.rst:303 msgid "x = MyClass()" msgstr "x = MyClass()" #: ../../tutorial/classes.rst:288 msgid "" "creates a new *instance* of the class and assigns this object to the local " "variable ``x``." msgstr "建立 class 的一個新\\ *實例*,並將此物件指派給區域變數 ``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:`~object.__init__`, like this::" msgstr "" "實例化運算(「呼叫」一個 class 物件)會建立一個空的物件。許多 class 喜歡在建" "立物件時有著自訂的特定實例初始狀態。因此,class 可以定義一個名為 :meth:" "`~object.__init__` 的特別 method,像這樣: ::" #: ../../tutorial/classes.rst:296 msgid "" "def __init__(self):\n" " self.data = []" msgstr "" "def __init__(self):\n" " self.data = []" #: ../../tutorial/classes.rst:299 msgid "" "When a class defines an :meth:`~object.__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 "" "當 class 定義了 :meth:`~object.__init__` method,class 實例化會為新建的 " "class 實例自動調用 :meth:`!__init__`。所以在這個範例中,一個新的、初始化的實" "例可以如此獲得: ::" #: ../../tutorial/classes.rst:305 msgid "" "Of course, the :meth:`~object.__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:`~object.__init__` method 可能為了更多的彈性而有引數。在這種情況" "下,要給 class 實例化運算子的引數會被傳遞給 :meth:`!__init__`。例如: ::" #: ../../tutorial/classes.rst:309 msgid "" ">>> class Complex:\n" "... def __init__(self, realpart, imagpart):\n" "... self.r = realpart\n" "... self.i = imagpart\n" "...\n" ">>> x = Complex(3.0, -4.5)\n" ">>> x.r, x.i\n" "(3.0, -4.5)" msgstr "" ">>> class Complex:\n" "... def __init__(self, realpart, imagpart):\n" "... self.r = realpart\n" "... self.i = imagpart\n" "...\n" ">>> x = Complex(3.0, -4.5)\n" ">>> x.r, x.i\n" "(3.0, -4.5)" #: ../../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 "" "現在,我們可以如何處理實例物件?實例物件能理解的唯一運算就是屬性參照。有兩種" "有效的屬性名稱:資料屬性 (data attribute) 和 method。" #: ../../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 "" "*資料屬性*\\ 對應 Smalltalk 中的「實例變數」,以及 C++ 中的「資料成員」。資料" "屬性不需要被宣告;和區域變數一樣,它們在第一次被賦值時就會立即存在。例如,如" "果 ``x`` 是 :class:`!MyClass` 在上述例子中建立的實例,下面的程式碼將印出值 " "``16``,而不留下蹤跡: ::" #: ../../tutorial/classes.rst:334 msgid "" "x.counter = 1\n" "while x.counter < 10:\n" " x.counter = x.counter * 2\n" "print(x.counter)\n" "del x.counter" msgstr "" "x.counter = 1\n" "while x.counter < 10:\n" " x.counter = x.counter * 2\n" "print(x.counter)\n" "del x.counter" #: ../../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." msgstr "" #: ../../tutorial/classes.rst:345 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 "" "實例物件的有效 method 名稱取決於其 class。根據定義,一個 class 中所有的函式物" "件屬性,就定義了實例的對應 method。所以在我們的例子中,``x.f`` 是一個有效的 " "method 參照,因為 ``MyClass.f`` 是一個函式,但 ``x.i`` 不是,因為 ``MyClass." "i`` 不是。但 ``x.f`` 與 ``MyClass.f`` 是不一樣的——它是一個 *method 物件*,而" "不是函式物件。" #: ../../tutorial/classes.rst:356 msgid "Method Objects" msgstr "Method 物件" #: ../../tutorial/classes.rst:358 msgid "Usually, a method is called right after it is bound::" msgstr "通常,一個 method 在它被連結後隨即被呼叫: ::" #: ../../tutorial/classes.rst:360 msgid "x.f()" msgstr "x.f()" #: ../../tutorial/classes.rst:362 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'``。然而,並沒有必" "要立即呼叫一個 method:``x.f`` 是一個 method 物件,並且可以被儲藏起來,之後再" "被呼叫。舉例來說: ::" #: ../../tutorial/classes.rst:366 msgid "" "xf = x.f\n" "while True:\n" " print(xf())" msgstr "" "xf = x.f\n" "while True:\n" " print(xf())" #: ../../tutorial/classes.rst:370 msgid "will continue to print ``hello world`` until the end of time." msgstr "將會持續印出 ``hello world`` 直到天荒地老。" #: ../../tutorial/classes.rst:372 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 "" "當一個 method 被呼叫時究竟會發生什麼事?你可能已經注意到 ``x.f()`` 被呼叫時沒" "有任何的引數,儘管 :meth:`!f` 的函式定義有指定一個引數。這個引數發生了什麼" "事?當一個需要引數的函式被呼叫而沒有給任何引數時,Python 肯定會引發例外——即使" "該引數實際上沒有被使用..." #: ../../tutorial/classes.rst:378 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 "" "事實上,你可能已經猜到了答案:method 的特殊之處在於,實例物件會作為函式中的第" "一個引數被傳遞。在我們的例子中,``x.f()`` 這個呼叫等同於 ``MyClass.f(x)``。一" "般來說,呼叫一個有 *n* 個引數的 method,等同於呼叫一個對應函式,其引數列表 " "(argument list) 被建立時,會在第一個引數前插入該 method 的實例物件。" #: ../../tutorial/classes.rst:385 msgid "" "In general, methods work as follows. 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, references to " "both the instance object and the function object are packed into a 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 "" "一般來說,方法的工作原理如下。當一個實例的非資料屬性被參照時,將會搜尋該實例" "的 class。如果該名稱是一個有效的 class 屬性,而且是一個函式物件,則對實例物件" "和函式物件的參照都會被打包到方法物件中。當使用引數串列呼叫方法物件時,會根據" "實例物件和引數串列來建構一個新的引數串列,並使用該新引數串列來呼叫函式物件。" #: ../../tutorial/classes.rst:398 msgid "Class and Instance Variables" msgstr "Class 及實例變數" #: ../../tutorial/classes.rst:400 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 "" "一般來說,實例變數用於每一個實例的獨特資料,而 class 變數用於該 class 的所有" "實例共享的屬性和 method: ::" #: ../../tutorial/classes.rst:404 msgid "" "class Dog:\n" "\n" " kind = 'canine' # class variable shared by all instances\n" "\n" " def __init__(self, name):\n" " self.name = name # instance variable unique to each instance\n" "\n" ">>> d = Dog('Fido')\n" ">>> e = Dog('Buddy')\n" ">>> d.kind # shared by all dogs\n" "'canine'\n" ">>> e.kind # shared by all dogs\n" "'canine'\n" ">>> d.name # unique to d\n" "'Fido'\n" ">>> e.name # unique to e\n" "'Buddy'" msgstr "" #: ../../tutorial/classes.rst:422 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` 物件," "如 list 和 dictionary,可能會產生意外的影響。舉例來說,下列程式碼的 *tricks* " "list 不應該作為一個 class 變數使用,因為這個 list 將會被所有的 *Dog* 實例所共" "享: ::" #: ../../tutorial/classes.rst:428 msgid "" "class Dog:\n" "\n" " tricks = [] # mistaken use of a class variable\n" "\n" " def __init__(self, name):\n" " self.name = name\n" "\n" " def add_trick(self, trick):\n" " self.tricks.append(trick)\n" "\n" ">>> d = Dog('Fido')\n" ">>> e = Dog('Buddy')\n" ">>> d.add_trick('roll over')\n" ">>> e.add_trick('play dead')\n" ">>> d.tricks # unexpectedly shared by all dogs\n" "['roll over', 'play dead']" msgstr "" #: ../../tutorial/classes.rst:445 msgid "Correct design of the class should use an instance variable instead::" msgstr "正確的 class 設計應該使用實例變數: ::" #: ../../tutorial/classes.rst:447 msgid "" "class Dog:\n" "\n" " def __init__(self, name):\n" " self.name = name\n" " self.tricks = [] # creates a new empty list for each dog\n" "\n" " def add_trick(self, trick):\n" " self.tricks.append(trick)\n" "\n" ">>> d = Dog('Fido')\n" ">>> e = Dog('Buddy')\n" ">>> d.add_trick('roll over')\n" ">>> e.add_trick('play dead')\n" ">>> d.tricks\n" "['roll over']\n" ">>> e.tricks\n" "['play dead']" msgstr "" #: ../../tutorial/classes.rst:469 msgid "Random Remarks" msgstr "隨意的備註" #: ../../tutorial/classes.rst:473 msgid "" "If the same attribute name occurs in both an instance and in a class, then " "attribute lookup prioritizes the instance::" msgstr "" "如果屬性名稱同時出現在一個實例和一個 class 中,則屬性的尋找會以實例為優" "先: ::" #: ../../tutorial/classes.rst:476 msgid "" ">>> class Warehouse:\n" "... purpose = 'storage'\n" "... region = 'west'\n" "...\n" ">>> w1 = Warehouse()\n" ">>> print(w1.purpose, w1.region)\n" "storage west\n" ">>> w2 = Warehouse()\n" ">>> w2.region = 'east'\n" ">>> print(w2.purpose, w2.region)\n" "storage east" msgstr "" ">>> class Warehouse:\n" "... purpose = 'storage'\n" "... region = 'west'\n" "...\n" ">>> w1 = Warehouse()\n" ">>> print(w1.purpose, w1.region)\n" "storage west\n" ">>> w2 = Warehouse()\n" ">>> w2.region = 'east'\n" ">>> print(w2.purpose, w2.region)\n" "storage east" #: ../../tutorial/classes.rst:488 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 "" "資料屬性可能被 method 或是被物件的一般使用者(「客戶端」)所參照。也就是說," "class 不可用於實作純粹抽象的資料型別。事實上,在 Python 中沒有任何可能的方" "法,可強制隱藏資料——這都是基於慣例。(另一方面,以 C 編寫的 Python 實作可以完" "全隱藏實作細節並且在必要時控制物件的存取;這可以被以 C 編寫的 Python 擴充所使" "用。)" #: ../../tutorial/classes.rst:496 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 "" "客戶端應該小心使用資料屬性——客戶端可能會因為覆寫他們的資料屬性,而破壞了被 " "method 維護的不變性。注意,客戶端可以增加他們自己的資料屬性到實例物件,但不影" "響 method 的有效性,只要避免名稱衝突即可——再一次提醒,命名慣例可以在這裡節省" "很多麻煩。" #: ../../tutorial/classes.rst:502 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 "" "在 method 中參照資料屬性(或其他 method!)是沒有簡寫的。我發現這實際上增加" "了 method 的可閱讀性:在瀏覽 method 時,絕不會混淆區域變數和實例變數。" #: ../../tutorial/classes.rst:507 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 程式設計師來說可讀性較低,此外,也可以想像一個可能因信任此慣例而編" "寫的 *class 瀏覽器 (browser)* 程式。" #: ../../tutorial/classes.rst:513 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 "" "任何一個作為 class 屬性的函式物件都為該 class 的實例定義了一個相應的 method。" "函式定義不一定要包含在 class definition 的文本中:將函式物件指定給 class 中的" "區域變數也是可以的。例如: ::" #: ../../tutorial/classes.rst:518 msgid "" "# Function defined outside the class\n" "def f1(self, x, y):\n" " return min(x, x+y)\n" "\n" "class C:\n" " f = f1\n" "\n" " def g(self):\n" " return 'hello world'\n" "\n" " h = g" msgstr "" #: ../../tutorial/classes.rst:530 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 :class:`!C` 的屬性,並指向函式物件,所" "以他們都是class :class:`!C` 實例的 method —— ``h`` 與 ``g`` 是完全一樣的。請" "注意,這種做法通常只會使該程式的讀者感到困惑。" #: ../../tutorial/classes.rst:535 msgid "" "Methods may call other methods by using method attributes of the ``self`` " "argument::" msgstr "Method 可以藉由使用 ``self`` 引數的 method 屬性,呼叫其他 method: ::" #: ../../tutorial/classes.rst:538 msgid "" "class Bag:\n" " def __init__(self):\n" " self.data = []\n" "\n" " def add(self, x):\n" " self.data.append(x)\n" "\n" " def addtwice(self, x):\n" " self.add(x)\n" " self.add(x)" msgstr "" "class Bag:\n" " def __init__(self):\n" " self.data = []\n" "\n" " def add(self, x):\n" " self.data.append(x)\n" "\n" " def addtwice(self, x):\n" " self.add(x)\n" " self.add(x)" #: ../../tutorial/classes.rst:549 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 "" "Method 可以用與一般函式相同的方式參照全域名稱。與 method 相關的全域作用域,就" "是包含其定義的模組。(class 永遠不會被用作全域作用域。)雖然人們很少有在 " "method 中使用全域資料的充分理由,但全域作用域仍有許多合法的使用:比方說,被 " "import 至全域作用域的函式和模組,可以被 method 以及在該作用域中定義的函式和 " "class 所使用。通常,包含 method 的 class,它本身就是被定義在這個全域作用域," "在下一節,我們將看到 method 想要參照自己的 class 的一些好原因。" #: ../../tutorial/classes.rst:559 msgid "" "Each value is an object, and therefore has a *class* (also called its " "*type*). It is stored as ``object.__class__``." msgstr "" "每個值都是一個物件,因此都具有一個 *class*,也可以稱為它的 *type(型別)*。它" "以 ``object.__class__`` 被儲存。" #: ../../tutorial/classes.rst:566 msgid "Inheritance" msgstr "繼承 (Inheritance)" #: ../../tutorial/classes.rst:568 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 "" "當然,如果沒有支援繼承,「class」這個語言特色就不值得被稱為 class。一個 " "derived class(衍生類別)定義的語法看起來如下: ::" #: ../../tutorial/classes.rst:572 msgid "" "class DerivedClassName(BaseClassName):\n" " \n" " .\n" " .\n" " .\n" " " msgstr "" "class DerivedClassName(BaseClassName):\n" " \n" " .\n" " .\n" " .\n" " " #: ../../tutorial/classes.rst:579 msgid "" "The name :class:`!BaseClassName` must be defined in a namespace accessible " "from the 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` 必須被定義於作用域可及的命名空間,且該作用域要包" "含 derived class 定義。要代替 base class(基底類別)的名稱,用其他任意的運算" "式也是被允許的。這會很有用,例如,當一個 base class 是在另一個模組中被定義" "時: ::" #: ../../tutorial/classes.rst:585 msgid "class DerivedClassName(modname.BaseClassName):" msgstr "class DerivedClassName(modname.BaseClassName):" #: ../../tutorial/classes.rst:587 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 "" "執行 derived class 定義的過程,與執行 base class 相同。當 class 物件被建構" "時,base class 會被記住。這是用於解析屬性參照:如果一個要求的屬性無法在該 " "class 中找到,則會繼續在 base class 中搜尋。假如該 base class 本身也是衍生自" "其他 class,則這個規則會遞迴地被應用。" #: ../../tutorial/classes.rst:593 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 "" "關於 derived class 的實例化並沒有特別之處:``DerivedClassName()`` 會建立該 " "class 的一個新實例。Method 的參照被解析如下:對應的 class 屬性會被搜尋,如果" "需要,沿著 base class 的繼承鍊往下走,如果這產生了一個函式物件,則該 method " "的參照是有效的。" #: ../../tutorial/classes.rst:599 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 "" "Derived class 可以覆寫其 base class 的 method。因為 method 在呼叫同一個物件的" "其他 method 時沒有特別的特權,所以當 base class 的一個 method 在呼叫相同 " "base class 中定義的另一個 method 時,最終可能會呼叫到一個覆寫它的 derived " "class 中的 method。(給 C++ 程式設計師:Python 中所有 method 實際上都是 " "``virtual``。)" #: ../../tutorial/classes.rst:605 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 "" "一個在 derived class 覆寫的 method 可能事實上是想要擴充而非單純取代 base " "class 中相同名稱的 method。要直接呼叫 base class 的 method 有一個簡單的方法:" "只要呼叫 ``BaseClassName.methodname(self, arguments)``。這有時對客戶端也很有" "用。(請注意,只有在 base class 在全域作用域可以用 ``BaseClassName`` 被存取" "時,這方法才有效。)" #: ../../tutorial/classes.rst:612 msgid "Python has two built-in functions that work with inheritance:" msgstr "Python 有兩個內建函式可以用於繼承:" #: ../../tutorial/classes.rst:614 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:618 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` 判斷 class 繼承:``issubclass(bool, int)`` 會是 " "``True``,因為 :class:`bool` 是 :class:`int` 的 subclass(子類別)。但是," "``issubclass(float, int)`` 是 ``False``,因為 :class:`float` 並不是 :class:" "`int` 的 subclass。" #: ../../tutorial/classes.rst:628 msgid "Multiple Inheritance" msgstr "多重繼承" #: ../../tutorial/classes.rst:630 msgid "" "Python supports a form of multiple inheritance as well. A class definition " "with multiple base classes looks like this::" msgstr "" "Python 也支援多重繼承的形式。一個有多個 base class 的 class definition 看起來" "像這樣子: ::" #: ../../tutorial/classes.rst:633 msgid "" "class DerivedClassName(Base1, Base2, Base3):\n" " \n" " .\n" " .\n" " .\n" " " msgstr "" "class DerivedClassName(Base1, Base2, Base3):\n" " \n" " .\n" " .\n" " .\n" " " #: ../../tutorial/classes.rst:640 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 "" "在大多數情況下,最簡單的例子裡,你可以這樣思考,對於繼承自 parent class(父類" "別)的屬性,其搜尋規則為:深度優先、從左到右、在階層裡重疊的相同 class 中不重" "複搜尋。因此,假如有一個屬性在 :class:`!DerivedClassName` 沒有被找到,則在 :" "class:`!Base1` 搜尋它,接著(遞迴地)在 :class:`!Base1` 的 base class 中搜" "尋,假如在那裡又沒有找到的話,會在 :class:`!Base2` 搜尋,依此類推。" #: ../../tutorial/classes.rst:647 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 "" "事實上,它稍微複雜一些;method 的解析順序是動態地變化,以支援對 :func:" "`super` 的合作呼叫。這個方式在其他的多重繼承語言中,稱為呼叫下一個方法 (call-" "next-method),且比在單一繼承語言中的 super call(超級呼叫)來得更強大。" #: ../../tutorial/classes.rst:653 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 :ref:`python_2.3_mro`." msgstr "" "動態排序是必要的,因為多重繼承的所有情況都表現一或多的菱形關係(其中至少一個 " "parent class 可以從最底層 class 透過多個路徑存取)。例如,所有的 class 都繼承" "自 :class:`object`,因此任何多重繼承的情況都提供了多個到達 :class:`object` 的" "路徑。為了避免 base class 被多次存取,動態演算法以這些方式將搜尋順序線性化 " "(linearize):保留每個 class 中規定的從左到右的順序、對每個 parent 只會呼叫一" "次、使用單調的 (monotonic) 方式(意思是,一個 class 可以被 subclassed(子類別" "化),而不會影響其 parent 的搜尋優先順序)。總之,這些特性使設計出可靠又可擴" "充、具有多重繼承的 class 成為可能。更多資訊,請見 :ref:`python_2.3_mro`。" #: ../../tutorial/classes.rst:670 msgid "Private Variables" msgstr "私有變數" #: ../../tutorial/classes.rst:672 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 "" "「私有」(private) 實例變數,指的是不在物件內部便無法存取的變數,這在 Python " "中是不存在的。但是,大多數 Python 的程式碼都遵守一個慣例:前綴為一個底線的名" "稱(如:``_spam``)應被視為 API (應用程式介面)的非公有 (non-public) 部分" "(無論它是函式、方法或是資料成員)。這被視為一個實作細節,如有調整,亦不另行" "通知。" #: ../../tutorial/classes.rst:682 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 "" "既然 class 私有的成員已有一個有效的用例(即避免名稱與 subclass 定義的名稱衝" "突),這種機制也存在另一個有限的支援,稱為 :dfn:`name mangling`\\ (名稱修" "飾)。任何格式為 ``__spam``\\ (至少兩個前導下底線,最多一個尾隨下底線)的物" "件名稱 (identifier) 會被文本地被替換為 ``_classname__spam``,在此 " "``classname`` 就是去掉前導下底線的當前 class 名稱。只要這個修飾是在 class 的" "定義之中發生,它就會在不考慮該物件名稱的語法位置的情況下完成。" #: ../../tutorial/classes.rst:693 msgid "" "The :ref:`private name mangling specifications ` for " "details and special cases." msgstr "" "參閱\\ :ref:`私有名稱修飾規格 `\\ 的詳情與特殊情況。" #: ../../tutorial/classes.rst:696 msgid "" "Name mangling is helpful for letting subclasses override methods without " "breaking intraclass method calls. For example::" msgstr "" "名稱修飾對於讓 subclass 覆寫 method 而不用破壞 class 內部的 method 呼叫,是有" "幫助的。舉例來說: ::" #: ../../tutorial/classes.rst:699 msgid "" "class Mapping:\n" " def __init__(self, iterable):\n" " self.items_list = []\n" " self.__update(iterable)\n" "\n" " def update(self, iterable):\n" " for item in iterable:\n" " self.items_list.append(item)\n" "\n" " __update = update # private copy of original update() method\n" "\n" "class MappingSubclass(Mapping):\n" "\n" " def update(self, keys, values):\n" " # provides new signature for update()\n" " # but does not break __init__()\n" " for item in zip(keys, values):\n" " self.items_list.append(item)" msgstr "" #: ../../tutorial/classes.rst:718 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`` class 中,它會被替換為 ``_Mapping__update``,而在 " "``MappingSubclass`` class 中,它會被替換為 ``_MappingSubclass__update``。" #: ../../tutorial/classes.rst:723 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 "" "請注意,修飾規則是被設計來避免意外;它仍可能存取或修改一個被視為私有的變數。" "這在特殊情況下甚至可能很有用,例如在除錯器 (debugger)。" #: ../../tutorial/classes.rst:727 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()`` 的程式碼不會把調用 class 的名稱視" "為當前的 class;這和 ``global`` 陳述式的效果類似,該效果同樣僅限於整體被位元" "組編譯後 (byte-compiled) 的程式碼。同樣的限制適用於 ``getattr()``," "``setattr()`` 和 ``delattr()``,以及直接參照 ``__dict__`` 時。" #: ../../tutorial/classes.rst:738 msgid "Odds and Ends" msgstr "補充說明" #: ../../tutorial/classes.rst:740 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:744 msgid "" "from dataclasses import dataclass\n" "\n" "@dataclass\n" "class Employee:\n" " name: str\n" " dept: str\n" " salary: int" msgstr "" "from dataclasses import dataclass\n" "\n" "@dataclass\n" "class Employee:\n" " name: str\n" " dept: str\n" " salary: int" #: ../../tutorial/classes.rst:754 msgid "" ">>> john = Employee('john', 'computer lab', 1000)\n" ">>> john.dept\n" "'computer lab'\n" ">>> john.salary\n" "1000" msgstr "" ">>> john = Employee('john', 'computer lab', 1000)\n" ">>> john.dept\n" "'computer lab'\n" ">>> john.salary\n" "1000" #: ../../tutorial/classes.rst:760 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:`~io.TextIOBase.read` " "and :meth:`~io.TextIOBase.readline` that get the data from a string buffer " "instead, and pass it as an argument." msgstr "" "用來處理特殊抽象資料型別的一段 Python 程式碼,經常能以傳遞一個 class 來替代," "此 class 模擬該資料型別的多種 method。例如,如果你有一個函式,它會從一個檔案" "物件來格式化某些資料,你也可以定義一個有 :meth:`~io.TextIOBase.read` 和 :" "meth:`~io.TextIOBase.readline` method 的 class 作為替代方式,從字串緩衝區取得" "資料,並將其作為引數來傳遞。" #: ../../tutorial/classes.rst:772 msgid "" ":ref:`Instance method objects ` have attributes, too: :" "attr:`m.__self__ ` is the instance object with the method :" "meth:`!m`, and :attr:`m.__func__ ` is the :ref:`function " "object ` corresponding to the method." msgstr "" ":ref:`實例的 method 物件 `\\ 也具有屬性::attr:`m.__self__ " "` 就是帶有 method :meth:`!m` 的實例物件,而 :attr:`m." "__func__ ` 則是該 method 所對應的\\ :ref:`函式物件 `。" #: ../../tutorial/classes.rst:782 msgid "Iterators" msgstr "疊代器 (Iterator)" #: ../../tutorial/classes.rst:784 msgid "" "By now you have probably noticed that most container objects can be looped " "over using a :keyword:`for` statement::" msgstr "" "到目前為止,你可能已經注意到大多數的容器 (container) 物件都可以使用 :keyword:" "`for` 陳述式來進行迴圈: ::" #: ../../tutorial/classes.rst:787 msgid "" "for element in [1, 2, 3]:\n" " print(element)\n" "for element in (1, 2, 3):\n" " print(element)\n" "for key in {'one':1, 'two':2}:\n" " print(key)\n" "for char in \"123\":\n" " print(char)\n" "for line in open(\"myfile.txt\"):\n" " print(line, end='')" msgstr "" "for element in [1, 2, 3]:\n" " print(element)\n" "for element in (1, 2, 3):\n" " print(element)\n" "for key in {'one':1, 'two':2}:\n" " print(key)\n" "for char in \"123\":\n" " print(char)\n" "for line in open(\"myfile.txt\"):\n" " print(line, end='')" #: ../../tutorial/classes.rst:798 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__` method,而此 method 會逐一" "存取容器中的元素。當元素用盡時,:meth:`~iterator.__next__` 將引發 :exc:" "`StopIteration` 例外,來通知 :keyword:`!for` 終止迴圈。你可以使用內建函式 :" "func:`next` 來呼叫 :meth:`~iterator.__next__` method;這個例子展示了它的運作" "方式: ::" #: ../../tutorial/classes.rst:807 msgid "" ">>> s = 'abc'\n" ">>> it = iter(s)\n" ">>> it\n" "\n" ">>> next(it)\n" "'a'\n" ">>> next(it)\n" "'b'\n" ">>> next(it)\n" "'c'\n" ">>> next(it)\n" "Traceback (most recent call last):\n" " File \"\", line 1, in \n" " next(it)\n" "StopIteration" msgstr "" ">>> s = 'abc'\n" ">>> it = iter(s)\n" ">>> it\n" "\n" ">>> next(it)\n" "'a'\n" ">>> next(it)\n" "'b'\n" ">>> next(it)\n" "'c'\n" ">>> next(it)\n" "Traceback (most recent call last):\n" " File \"\", line 1, in \n" " next(it)\n" "StopIteration" #: ../../tutorial/classes.rst:823 msgid "" "Having seen the mechanics behind the iterator protocol, it is easy to add " "iterator behavior to your classes. Define an :meth:`~container.__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 "" "看過疊代器協定的幕後機制後,在你的 class 加入疊代器的行為就很容易了。定義一" "個 :meth:`~container.__iter__` method 來回傳一個帶有 :meth:`~iterator." "__next__` method 的物件。如果 class 已定義了 :meth:`!__next__`,則 :meth:`!" "__iter__` 可以只回傳 ``self``: ::" #: ../../tutorial/classes.rst:828 msgid "" "class Reverse:\n" " \"\"\"Iterator for looping over a sequence backwards.\"\"\"\n" " def __init__(self, data):\n" " self.data = data\n" " self.index = len(data)\n" "\n" " def __iter__(self):\n" " return self\n" "\n" " def __next__(self):\n" " if self.index == 0:\n" " raise StopIteration\n" " self.index = self.index - 1\n" " return self.data[self.index]" msgstr "" #: ../../tutorial/classes.rst:845 msgid "" ">>> rev = Reverse('spam')\n" ">>> iter(rev)\n" "<__main__.Reverse object at 0x00A1DB50>\n" ">>> for char in rev:\n" "... print(char)\n" "...\n" "m\n" "a\n" "p\n" "s" msgstr "" ">>> rev = Reverse('spam')\n" ">>> iter(rev)\n" "<__main__.Reverse object at 0x00A1DB50>\n" ">>> for char in rev:\n" "... print(char)\n" "...\n" "m\n" "a\n" "p\n" "s" #: ../../tutorial/classes.rst:860 msgid "Generators" msgstr "產生器 (Generator)" #: ../../tutorial/classes.rst:862 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:869 msgid "" "def reverse(data):\n" " for index in range(len(data)-1, -1, -1):\n" " yield data[index]" msgstr "" "def reverse(data):\n" " for index in range(len(data)-1, -1, -1):\n" " yield data[index]" #: ../../tutorial/classes.rst:875 msgid "" ">>> for char in reverse('golf'):\n" "... print(char)\n" "...\n" "f\n" "l\n" "o\n" "g" msgstr "" ">>> for char in reverse('golf'):\n" "... print(char)\n" "...\n" "f\n" "l\n" "o\n" "g" #: ../../tutorial/classes.rst:883 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:`~iterator.__iter__` and :meth:`~generator." "__next__` methods are created automatically." msgstr "" "任何可以用產生器來完成的事,也能用以 class 為基礎的疊代器來完成,如同前一節的" "描述。而讓產生器的程式碼更為精簡的原因是,:meth:`~iterator.__iter__` 和 :" "meth:`~generator.__next__` method 會自動被建立。" #: ../../tutorial/classes.rst:888 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:893 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 "" "除了會自動建立 method 和儲存程式狀態,當產生器終止時,它們還會自動引發 :exc:" "`StopIteration`。這些特性結合在一起,使建立疊代器能與編寫常規函式一樣容易。" #: ../../tutorial/classes.rst:902 msgid "Generator Expressions" msgstr "產生器運算式" #: ../../tutorial/classes.rst:904 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 "" "某些簡單的產生器可以寫成如運算式一般的簡潔程式碼,所用的語法類似 list " "comprehension(串列綜合運算),但外層為括號而非方括號。這種運算式被設計用於產" "生器將立即被外圍函式 (enclosing function) 所使用的情況。產生器運算式與完整的" "產生器定義相比,程式碼較精簡但功能較少,也比等效的 list comprehension 更為節" "省記憶體。" #: ../../tutorial/classes.rst:911 msgid "Examples::" msgstr "例如: ::" #: ../../tutorial/classes.rst:913 msgid "" ">>> sum(i*i for i in range(10)) # sum of squares\n" "285\n" "\n" ">>> xvec = [10, 20, 30]\n" ">>> yvec = [7, 5, 3]\n" ">>> sum(x*y for x,y in zip(xvec, yvec)) # dot product\n" "260\n" "\n" ">>> unique_words = set(word for line in page for word in line.split())\n" "\n" ">>> valedictorian = max((student.gpa, student.name) for student in " "graduates)\n" "\n" ">>> data = 'golf'\n" ">>> list(data[i] for i in range(len(data)-1, -1, -1))\n" "['f', 'l', 'o', 'g']" msgstr "" #: ../../tutorial/classes.rst:932 msgid "Footnotes" msgstr "註解" #: ../../tutorial/classes.rst:933 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__`,它回" "傳用於實作模組命名空間的 dictionary;:attr:`~object.__dict__` 這個名稱是一個" "屬性但不是全域名稱。顯然,使用此屬性將違反命名空間實作的抽象化,而應該僅限用" "於事後除錯器 (post-mortem debugger) 之類的東西。" #: ../../tutorial/classes.rst:343 msgid "object" msgstr "object(物件)" #: ../../tutorial/classes.rst:343 msgid "method" msgstr "method(方法)" #: ../../tutorial/classes.rst:679 msgid "name" msgstr "name(名稱)" #: ../../tutorial/classes.rst:679 msgid "mangling" msgstr "mangling(修飾)" #~ 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 "" #~ "實例的另一種屬性參照是 *method*。Method 是一個「屬於」物件的函式。(在 " #~ "Python 中,術語 method 並不是 class 實例所獨有的:其他物件型別也可以有 " #~ "method。例如,list 物件具有稱為 append、insert、remove、sort 等 method。但" #~ "是,在下面的討論中,我們將用術語 method 來專門表示 class 實例物件的 " #~ "method,除非另有明確說明。)"