From b0f9ea700ec070847d06749dadcdf7caefaa390a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 15 Jul 2025 10:26:27 +0000 Subject: [PATCH 1/6] Initial plan From b3a4eb3f410e2f5280d370ca9a6abaa19efeba3d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 15 Jul 2025 10:35:12 +0000 Subject: [PATCH 2/6] Translate introduction and key sections of descriptor primer Co-authored-by: mattwang44 <24987826+mattwang44@users.noreply.github.com> --- howto/descriptor.po | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/howto/descriptor.po b/howto/descriptor.po index 8a489fafc2..0db2bc0dc9 100644 --- a/howto/descriptor.po +++ b/howto/descriptor.po @@ -57,12 +57,14 @@ msgid "" "The \"primer\" gives a basic overview, moving gently from simple examples, " "adding one feature at a time. Start here if you're new to descriptors." msgstr "" +"「入門」提供基本概述,從簡單範例開始逐步介紹,一次新增一個功能。如果你是描述器的新手,請從這裡開始。" #: ../../howto/descriptor.rst:21 msgid "" "The second section shows a complete, practical descriptor example. If you " "already know the basics, start there." msgstr "" +"第二個章節展示完整、實用的描述器範例。如果你已經了解基礎知識,可以從那裡開始。" #: ../../howto/descriptor.rst:24 msgid "" @@ -70,6 +72,7 @@ msgid "" "detailed mechanics of how descriptors work. Most people don't need this " "level of detail." msgstr "" +"第三個章節提供更技術性的教學,深入探討描述器運作的詳細機制。大部分的人不需要這種程度的細節。" #: ../../howto/descriptor.rst:28 msgid "" @@ -79,26 +82,29 @@ msgid "" "like :func:`classmethod`, :func:`staticmethod`, :func:`property`, " "and :term:`__slots__`." msgstr "" +"最後一個章節提供以 C 語言撰寫的內建描述器的純 Python 等價實作。如果你好奇函式如何轉變為綁定方法,或者想了解常見工具如 :func:`classmethod`、:func:`staticmethod`、:func:`property` 和 :term:`__slots__` 的實作方式,請閱讀此章節。" #: ../../howto/descriptor.rst:36 msgid "Primer" -msgstr "" +msgstr "入門" #: ../../howto/descriptor.rst:38 msgid "" "In this primer, we start with the most basic possible example and then we'll " "add new capabilities one by one." msgstr "" +"在此入門教學中,我們從最基礎的範例開始,然後逐一新增新功能。" #: ../../howto/descriptor.rst:43 msgid "Simple example: A descriptor that returns a constant" -msgstr "" +msgstr "簡單範例:回傳常數的描述器" #: ../../howto/descriptor.rst:45 msgid "" "The :class:`!Ten` class is a descriptor whose :meth:`~object.__get__` method " "always returns the constant ``10``:" msgstr "" +":class:`!Ten` 類別是一個描述器,它的 :meth:`~object.__get__` 方法總是回傳常數 ``10``:" #: ../../howto/descriptor.rst:48 msgid "" @@ -115,6 +121,7 @@ msgid "" "To use the descriptor, it must be stored as a class variable in another " "class:" msgstr "" +"要使用描述器,必須將它儲存為另一個類別的類別變數:" #: ../../howto/descriptor.rst:56 msgid "" @@ -128,6 +135,7 @@ msgid "" "An interactive session shows the difference between normal attribute lookup " "and descriptor lookup:" msgstr "" +"互動式工作階段顯示一般屬性查找和描述器查找之間的差異:" #: ../../howto/descriptor.rst:65 msgid "" @@ -145,33 +153,38 @@ msgid "" "descriptor instance, recognized by its ``__get__`` method. Calling that " "method returns ``10``." msgstr "" +"在 ``a.x`` 屬性查找中,點運算子在類別字典中找到 ``'x': 5``。在 ``a.y`` 查找中,點運算子找到一個描述器實例,透過其 ``__get__`` 方法來識別。呼叫該方法回傳 ``10``。" #: ../../howto/descriptor.rst:78 msgid "" "Note that the value ``10`` is not stored in either the class dictionary or " "the instance dictionary. Instead, the value ``10`` is computed on demand." msgstr "" +"請注意,數值 ``10`` 並不儲存在類別字典或實例字典中。相反地,數值 ``10`` 是按需計算的。" #: ../../howto/descriptor.rst:81 msgid "" "This example shows how a simple descriptor works, but it isn't very useful. " "For retrieving constants, normal attribute lookup would be better." msgstr "" +"這個範例顯示了簡單描述器的運作方式,但它並不是很有用。對於取得常數,一般的屬性查找會比較好。" #: ../../howto/descriptor.rst:84 msgid "" "In the next section, we'll create something more useful, a dynamic lookup." msgstr "" +"在下一個章節中,我們將建立更有用的東西:動態查找。" #: ../../howto/descriptor.rst:88 msgid "Dynamic lookups" -msgstr "" +msgstr "動態查找" #: ../../howto/descriptor.rst:90 msgid "" "Interesting descriptors typically run computations instead of returning " "constants:" msgstr "" +"有趣的描述器通常執行計算而不是回傳常數:" #: ../../howto/descriptor.rst:93 msgid "" @@ -195,6 +208,7 @@ msgid "" "An interactive session shows that the lookup is dynamic — it computes " "different, updated answers each time::" msgstr "" +"互動式工作階段顯示查找是動態的——每次都會計算不同的更新答案: ::" #: ../../howto/descriptor.rst:112 msgid "" @@ -221,10 +235,11 @@ msgid "" "parameter that lets the :meth:`~object.__get__` method learn the target " "directory. The *objtype* parameter is the class *Directory*." msgstr "" +"除了顯示描述器如何執行計算外,這個範例也揭示了 :meth:`~object.__get__` 參數的目的。*self* 參數是 *size*,一個 *DirectorySize* 的實例。*obj* 參數是 *g* 或 *s*,一個 *Directory* 的實例。正是 *obj* 參數讓 :meth:`~object.__get__` 方法得知目標目錄。*objtype* 參數是類別 *Directory*。" #: ../../howto/descriptor.rst:131 msgid "Managed attributes" -msgstr "" +msgstr "受管理的屬性" #: ../../howto/descriptor.rst:133 msgid "" @@ -235,6 +250,7 @@ msgid "" "and :meth:`~object.__set__` methods are triggered when the public attribute " "is accessed." msgstr "" +"描述器的一個常見用途是管理對實例資料的存取。描述器被指派給類別字典中的公開屬性,而實際資料則儲存為實例字典中的私有屬性。當存取公開屬性時,會觸發描述器的 :meth:`~object.__get__` 和 :meth:`~object.__set__` 方法。" #: ../../howto/descriptor.rst:139 msgid "" @@ -242,6 +258,7 @@ msgid "" "private attribute. When the public attribute is accessed, the descriptor " "logs the lookup or update:" msgstr "" +"在以下範例中,*age* 是公開屬性,*_age* 是私有屬性。當存取公開屬性時,描述器會記錄查找或更新:" #: ../../howto/descriptor.rst:143 msgid "" @@ -318,13 +335,14 @@ msgstr "" #: ../../howto/descriptor.rst:213 msgid "Customized names" -msgstr "" +msgstr "自訂名稱" #: ../../howto/descriptor.rst:215 msgid "" "When a class uses descriptors, it can inform each descriptor about which " "variable name was used." msgstr "" +"當類別使用描述器時,它可以告知每個描述器使用了哪個變數名稱。" #: ../../howto/descriptor.rst:218 msgid "" @@ -427,7 +445,7 @@ msgstr "" #: ../../howto/descriptor.rst:295 msgid "Closing thoughts" -msgstr "" +msgstr "結語" #: ../../howto/descriptor.rst:297 msgid "" @@ -435,6 +453,7 @@ msgid "" "defines :meth:`~object.__get__`, :meth:`~object.__set__`, " "or :meth:`~object.__delete__`." msgstr "" +":term:`描述器 ` 是我們對任何定義了 :meth:`~object.__get__`、:meth:`~object.__set__` 或 :meth:`~object.__delete__` 的物件的稱呼。" #: ../../howto/descriptor.rst:300 msgid "" From 747a9e490715adabdeaea21ce0172e0363a40330 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 15 Jul 2025 10:40:15 +0000 Subject: [PATCH 3/6] Complete major sections of descriptor primer translation Co-authored-by: mattwang44 <24987826+mattwang44@users.noreply.github.com> --- howto/descriptor.po | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/howto/descriptor.po b/howto/descriptor.po index 0db2bc0dc9..e90eec4fb2 100644 --- a/howto/descriptor.po +++ b/howto/descriptor.po @@ -294,6 +294,7 @@ msgid "" "An interactive session shows that all access to the managed attribute *age* " "is logged, but that the regular attribute *name* is not logged:" msgstr "" +"互動式工作階段顯示對受管理屬性 *age* 的所有存取都被記錄,但一般屬性 *name* 則不會被記錄:" #: ../../howto/descriptor.rst:181 msgid "" @@ -332,6 +333,7 @@ msgid "" "only have one logged attribute and that its name is unchangeable. In the " "next example, we'll fix that problem." msgstr "" +"這個範例的一個主要問題是私有名稱 *_age* 在 *LoggedAgeAccess* 類別中是硬編碼的。這意味著每個實例只能有一個被記錄的屬性,而且它的名稱是不可變的。在下一個範例中,我們將修正這個問題。" #: ../../howto/descriptor.rst:213 msgid "Customized names" @@ -352,6 +354,7 @@ msgid "" "names can be recorded, giving each descriptor its own *public_name* and " "*private_name*:" msgstr "" +"在這個範例中,:class:`!Person` 類別有兩個描述器實例:*name* 和 *age*。當定義 :class:`!Person` 類別時,它會對 *LoggedAccess* 中的 :meth:`~object.__set_name__` 進行回呼,以便記錄欄位名稱,讓每個描述器都有自己的 *public_name* 和 *private_name*:" #: ../../howto/descriptor.rst:223 msgid "" @@ -462,6 +465,7 @@ msgid "" "where it was created or the name of class variable it was assigned to. " "(This method, if present, is called even if the class is not a descriptor.)" msgstr "" +"描述器可以選擇性地擁有 :meth:`~object.__set_name__` 方法。這只在描述器需要知道建立它的類別或被指派的類別變數名稱時使用。(此方法如果存在,即使類別不是描述器也會被呼叫。)" #: ../../howto/descriptor.rst:305 msgid "" @@ -469,18 +473,21 @@ msgid "" "descriptor is accessed indirectly with ``vars(some_class)" "[descriptor_name]``, the descriptor instance is returned without invoking it." msgstr "" +"描述器在屬性查找期間由點運算子呼叫。如果描述器是透過 ``vars(some_class)[descriptor_name]`` 間接存取,會回傳描述器實例而不呼叫它。" #: ../../howto/descriptor.rst:309 msgid "" "Descriptors only work when used as class variables. When put in instances, " "they have no effect." msgstr "" +"描述器只有在用作類別變數時才能運作。當放在實例中時,它們沒有效果。" #: ../../howto/descriptor.rst:312 msgid "" "The main motivation for descriptors is to provide a hook allowing objects " "stored in class variables to control what happens during attribute lookup." msgstr "" +"描述器的主要動機是提供一個掛鉤,讓儲存在類別變數中的物件能夠控制屬性查找期間發生的事情。" #: ../../howto/descriptor.rst:315 msgid "" @@ -488,6 +495,7 @@ msgid "" "Descriptors invert that relationship and allow the data being looked-up to " "have a say in the matter." msgstr "" +"傳統上,呼叫的類別控制查找期間發生的事情。描述器顛倒了這種關係,讓被查找的資料在這件事上有發言權。" #: ../../howto/descriptor.rst:319 msgid "" @@ -496,6 +504,7 @@ msgid "" "like :func:`classmethod`, :func:`staticmethod`, :func:`property`, " "and :func:`functools.cached_property` are all implemented as descriptors." msgstr "" +"描述器在整個語言中被廣泛使用。函式就是透過這種方式轉變為綁定方法。常見工具如 :func:`classmethod`、:func:`staticmethod`、:func:`property` 和 :func:`functools.cached_property` 都是以描述器實作的。" #: ../../howto/descriptor.rst:326 msgid "Complete Practical Example" From 58f99a2574bb06ce03084e355a55885a14fca46e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 16 Jul 2025 03:57:18 +0000 Subject: [PATCH 4/6] Fix line breaks and translate Complete Practical Example section Co-authored-by: mattwang44 <24987826+mattwang44@users.noreply.github.com> --- howto/descriptor.po | 150 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 143 insertions(+), 7 deletions(-) diff --git a/howto/descriptor.po b/howto/descriptor.po index e90eec4fb2..bd342eec1f 100644 --- a/howto/descriptor.po +++ b/howto/descriptor.po @@ -129,6 +129,9 @@ msgid "" " x = 5 # Regular class attribute\n" " y = Ten() # Descriptor instance" msgstr "" +"class A:\n" +" x = 5 # 一般類別屬性\n" +" y = Ten() # 描述器實例" #: ../../howto/descriptor.rst:62 msgid "" @@ -145,6 +148,11 @@ msgid "" ">>> a.y # Descriptor lookup\n" "10" msgstr "" +">>> a = A() # 建立類別 A 的實例\n" +">>> a.x # 一般屬性查找\n" +"5\n" +">>> a.y # 描述器查找\n" +"10" #: ../../howto/descriptor.rst:73 msgid "" @@ -202,6 +210,19 @@ msgid "" " def __init__(self, dirname):\n" " self.dirname = dirname # Regular instance attribute" msgstr "" +"import os\n" +"\n" +"class DirectorySize:\n" +"\n" +" def __get__(self, obj, objtype=None):\n" +" return len(os.listdir(obj.dirname))\n" +"\n" +"class Directory:\n" +"\n" +" size = DirectorySize() # 描述器實例\n" +"\n" +" def __init__(self, dirname):\n" +" self.dirname = dirname # 一般實例屬性" #: ../../howto/descriptor.rst:109 msgid "" @@ -225,6 +246,15 @@ msgid "" "updated\n" "2" msgstr "" +">>> s = Directory('songs')\n" +">>> g = Directory('games')\n" +">>> s.size # songs 目錄有二十個檔案\n" +"20\n" +">>> g.size # games 目錄有三個檔案\n" +"3\n" +">>> os.remove('games/chess') # 刪除一個遊戲\n" +">>> g.size # 檔案數量自動更新\n" +"2" #: ../../howto/descriptor.rst:122 msgid "" @@ -288,6 +318,31 @@ msgid "" " def birthday(self):\n" " self.age += 1 # Calls both __get__() and __set__()" msgstr "" +"import logging\n" +"\n" +"logging.basicConfig(level=logging.INFO)\n" +"\n" +"class LoggedAgeAccess:\n" +"\n" +" def __get__(self, obj, objtype=None):\n" +" value = obj._age\n" +" logging.info('Accessing %r giving %r', 'age', value)\n" +" return value\n" +"\n" +" def __set__(self, obj, value):\n" +" logging.info('Updating %r to %r', 'age', value)\n" +" obj._age = value\n" +"\n" +"class Person:\n" +"\n" +" age = LoggedAgeAccess() # 描述器實例\n" +"\n" +" def __init__(self, name, age):\n" +" self.name = name # 一般實例屬性\n" +" self.age = age # 呼叫 __set__()\n" +"\n" +" def birthday(self):\n" +" self.age += 1 # 同時呼叫 __get__() 和 __set__()" #: ../../howto/descriptor.rst:172 msgid "" @@ -325,6 +380,28 @@ msgid "" "INFO:root:Accessing 'age' giving 40\n" "40" msgstr "" +">>> mary = Person('Mary M', 30) # 初始的 age 更新被記錄\n" +"INFO:root:Updating 'age' to 30\n" +">>> dave = Person('David D', 40)\n" +"INFO:root:Updating 'age' to 40\n" +"\n" +">>> vars(mary) # 實際資料在私有屬性中\n" +"{'name': 'Mary M', '_age': 30}\n" +">>> vars(dave)\n" +"{'name': 'David D', '_age': 40}\n" +"\n" +">>> mary.age # 存取資料並記錄查找\n" +"INFO:root:Accessing 'age' giving 30\n" +"30\n" +">>> mary.birthday() # 更新也會被記錄\n" +"INFO:root:Accessing 'age' giving 30\n" +"INFO:root:Updating 'age' to 31\n" +"\n" +">>> dave.name # 一般屬性查找不會被記錄\n" +"'David D'\n" +">>> dave.age # 只有受管理的屬性會被記錄\n" +"INFO:root:Accessing 'age' giving 40\n" +"40" #: ../../howto/descriptor.rst:206 msgid "" @@ -389,6 +466,36 @@ msgid "" " def birthday(self):\n" " self.age += 1" msgstr "" +"import logging\n" +"\n" +"logging.basicConfig(level=logging.INFO)\n" +"\n" +"class LoggedAccess:\n" +"\n" +" def __set_name__(self, owner, name):\n" +" self.public_name = name\n" +" self.private_name = '_' + name\n" +"\n" +" def __get__(self, obj, objtype=None):\n" +" value = getattr(obj, self.private_name)\n" +" logging.info('Accessing %r giving %r', self.public_name, value)\n" +" return value\n" +"\n" +" def __set__(self, obj, value):\n" +" logging.info('Updating %r to %r', self.public_name, value)\n" +" setattr(obj, self.private_name, value)\n" +"\n" +"class Person:\n" +"\n" +" name = LoggedAccess() # 第一個描述器實例\n" +" age = LoggedAccess() # 第二個描述器實例\n" +"\n" +" def __init__(self, name, age):\n" +" self.name = name # 呼叫第一個描述器\n" +" self.age = age # 呼叫第二個描述器\n" +"\n" +" def birthday(self):\n" +" self.age += 1" #: ../../howto/descriptor.rst:256 msgid "" @@ -508,17 +615,18 @@ msgstr "" #: ../../howto/descriptor.rst:326 msgid "Complete Practical Example" -msgstr "" +msgstr "完整實用範例" #: ../../howto/descriptor.rst:328 msgid "" "In this example, we create a practical and powerful tool for locating " "notoriously hard to find data corruption bugs." msgstr "" +"在這個範例中,我們建立一個實用且強大的工具,用於找出惡名昭彰且難以發現的資料損壞錯誤。" #: ../../howto/descriptor.rst:333 msgid "Validator class" -msgstr "" +msgstr "驗證器類別" #: ../../howto/descriptor.rst:335 msgid "" @@ -527,12 +635,14 @@ msgid "" "restrictions. If those restrictions aren't met, it raises an exception to " "prevent data corruption at its source." msgstr "" +"驗證器是用於受管理屬性存取的描述器。在儲存任何資料之前,它會驗證新數值是否符合各種型別和範圍限制。如果不符合這些限制,它會引發例外以防止資料在源頭被損壞。" #: ../../howto/descriptor.rst:340 msgid "" "This :class:`!Validator` class is both an :term:`abstract base class` and a " "managed attribute descriptor:" msgstr "" +"這個 :class:`!Validator` 類別既是 :term:`抽象基底類別 ` 也是受管理屬性描述器:" #: ../../howto/descriptor.rst:343 msgid "" @@ -577,19 +687,21 @@ msgid "" "Custom validators need to inherit from :class:`!Validator` and must supply " "a :meth:`!validate` method to test various restrictions as needed." msgstr "" +"自訂驗證器需要繼承自 :class:`!Validator` 並且必須提供 :meth:`!validate` 方法來依需要測試各種限制。" #: ../../howto/descriptor.rst:368 msgid "Custom validators" -msgstr "" +msgstr "自訂驗證器" #: ../../howto/descriptor.rst:370 msgid "Here are three practical data validation utilities:" -msgstr "" +msgstr "以下是三個實用的資料驗證工具:" #: ../../howto/descriptor.rst:372 msgid "" ":class:`!OneOf` verifies that a value is one of a restricted set of options." msgstr "" +":class:`!OneOf` 驗證數值是否為限制選項集合中的其中一個。" #: ../../howto/descriptor.rst:374 msgid "" @@ -597,6 +709,7 @@ msgid "" "or :class:`float`. Optionally, it verifies that a value is between a given " "minimum or maximum." msgstr "" +":class:`!Number` 驗證數值是否為 :class:`int` 或 :class:`float`。可選地,它會驗證數值是否在給定的最小值或最大值之間。" #: ../../howto/descriptor.rst:378 msgid "" @@ -605,6 +718,7 @@ msgid "" "`predicate `_ " "as well." msgstr "" +":class:`!String` 驗證數值是否為 :class:`str`。可選地,它會驗證給定的最小或最大長度。它還可以驗證使用者定義的 `述詞 `_。" #: ../../howto/descriptor.rst:383 msgid "" @@ -664,11 +778,11 @@ msgstr "" #: ../../howto/descriptor.rst:439 msgid "Practical application" -msgstr "" +msgstr "實際應用" #: ../../howto/descriptor.rst:441 msgid "Here's how the data validators can be used in a real class:" -msgstr "" +msgstr "以下展示如何在真實類別中使用資料驗證器:" #: ../../howto/descriptor.rst:443 msgid "" @@ -686,7 +800,7 @@ msgstr "" #: ../../howto/descriptor.rst:456 msgid "The descriptors prevent invalid instances from being created:" -msgstr "" +msgstr "描述器防止建立無效的實例:" #: ../../howto/descriptor.rst:458 msgid "" @@ -714,6 +828,28 @@ msgid "" "\n" ">>> c = Component('WIDGET', 'metal', 5) # Allowed: The inputs are valid" msgstr "" +">>> Component('Widget', 'metal', 5) # 被阻止:'Widget' 不是全大寫\n" +"Traceback (most recent call last):\n" +" ...\n" +"ValueError: Expected to be true for " +"'Widget'\n" +"\n" +">>> Component('WIDGET', 'metle', 5) # 被阻止:'metle' 拼寫錯誤\n" +"Traceback (most recent call last):\n" +" ...\n" +"ValueError: Expected 'metle' to be one of {'metal', 'plastic', 'wood'}\n" +"\n" +">>> Component('WIDGET', 'metal', -5) # 被阻止:-5 是負數\n" +"Traceback (most recent call last):\n" +" ...\n" +"ValueError: Expected -5 to be at least 0\n" +"\n" +">>> Component('WIDGET', 'metal', 'V') # 被阻止:'V' 不是數字\n" +"Traceback (most recent call last):\n" +" ...\n" +"TypeError: Expected 'V' to be an int or float\n" +"\n" +">>> c = Component('WIDGET', 'metal', 5) # 允許:輸入有效" #: ../../howto/descriptor.rst:484 msgid "Technical Tutorial" From 8b53da48a69a1f5120bbf83efd5d1498eac139aa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 16 Jul 2025 04:01:06 +0000 Subject: [PATCH 5/6] Continue translating Technical Tutorial section with key concepts Co-authored-by: mattwang44 <24987826+mattwang44@users.noreply.github.com> --- howto/descriptor.po | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/howto/descriptor.po b/howto/descriptor.po index bd342eec1f..054f1633b7 100644 --- a/howto/descriptor.po +++ b/howto/descriptor.po @@ -853,13 +853,14 @@ msgstr "" #: ../../howto/descriptor.rst:484 msgid "Technical Tutorial" -msgstr "" +msgstr "技術教學" #: ../../howto/descriptor.rst:486 msgid "" "What follows is a more technical tutorial for the mechanics and details of " "how descriptors work." msgstr "" +"接下來是關於描述器運作機制和細節的更技術性教學。" #: ../../howto/descriptor.rst:491 msgid "Abstract" @@ -870,16 +871,18 @@ msgid "" "Defines descriptors, summarizes the protocol, and shows how descriptors are " "called. Provides an example showing how object relational mappings work." msgstr "" +"定義描述器、總結協定,並展示描述器如何被呼叫。提供展示物件關聯映射如何運作的範例。" #: ../../howto/descriptor.rst:496 msgid "" "Learning about descriptors not only provides access to a larger toolset, it " "creates a deeper understanding of how Python works." msgstr "" +"學習描述器不僅提供更大的工具集,還能更深入理解 Python 的運作方式。" #: ../../howto/descriptor.rst:501 msgid "Definition and introduction" -msgstr "" +msgstr "定義與介紹" #: ../../howto/descriptor.rst:503 msgid "" @@ -889,6 +892,7 @@ msgid "" "and :meth:`~object.__delete__`. If any of those methods are defined for an " "attribute, it is said to be a :term:`descriptor`." msgstr "" +"一般來說,描述器是具有描述器協定中某個方法的屬性值。這些方法包括 :meth:`~object.__get__`、:meth:`~object.__set__` 和 :meth:`~object.__delete__`。如果為屬性定義了其中任何一個方法,就稱為 :term:`描述器 `。" #: ../../howto/descriptor.rst:508 msgid "" @@ -901,6 +905,10 @@ msgid "" "Where this occurs in the precedence chain depends on which descriptor " "methods were defined." msgstr "" +"屬性存取的預設行為是從物件的字典中取得、設定或刪除屬性。例如,``a.x`` 有一個查找鏈," +"從 ``a.__dict__['x']`` 開始,然後是 ``type(a).__dict__['x']``,並繼續通過 ``type(a)`` " +"的方法解析順序。如果查找到的值是定義了其中一個描述器方法的物件,那麼 Python " +"可能會覆蓋預設行為並改為呼叫描述器方法。這在優先順序鏈中發生的位置取決於定義了哪些描述器方法。" #: ../../howto/descriptor.rst:517 msgid "" @@ -910,6 +918,9 @@ msgid "" "simplify the underlying C code and offer a flexible set of new tools for " "everyday Python programs." msgstr "" +"描述器是強大且通用的協定。它們是屬性、方法、靜態方法、類別方法和 :func:`super` " +"背後的機制。它們在 Python 本身中廣泛使用。描述器簡化了底層 C 程式碼," +"並為日常 Python 程式提供靈活的新工具集。" #: ../../howto/descriptor.rst:525 msgid "Descriptor protocol" @@ -933,6 +944,7 @@ msgid "" "considered a descriptor and can override default behavior upon being looked " "up as an attribute." msgstr "" +"就是這樣而已。定義其中任何一個方法,物件就被視為描述器,並且可以在作為屬性被查找時覆蓋預設行為。" #: ../../howto/descriptor.rst:537 msgid "" @@ -941,6 +953,8 @@ msgid "" "define :meth:`~object.__get__` are called non-data descriptors (they are " "often used for methods but other uses are possible)." msgstr "" +"如果物件定義了 :meth:`~object.__set__` 或 :meth:`~object.__delete__`,它被視為資料描述器。" +"只定義 :meth:`~object.__get__` 的描述器稱為非資料描述器(它們通常用於方法,但也有其他用途)。" #: ../../howto/descriptor.rst:542 msgid "" @@ -950,6 +964,8 @@ msgid "" "takes precedence. If an instance's dictionary has an entry with the same " "name as a non-data descriptor, the dictionary entry takes precedence." msgstr "" +"資料描述器和非資料描述器在如何計算相對於實例字典條目的覆蓋方面有所不同。如果實例的字典有與資料描述器同名的條目," +"資料描述器具有優先權。如果實例的字典有與非資料描述器同名的條目,字典條目具有優先權。" #: ../../howto/descriptor.rst:548 msgid "" @@ -959,16 +975,20 @@ msgid "" "method with an exception raising placeholder is enough to make it a data " "descriptor." msgstr "" +"要建立唯讀資料描述器,定義 :meth:`~object.__get__` 和 :meth:`~object.__set__`," +"並讓 :meth:`~object.__set__` 在被呼叫時引發 :exc:`AttributeError`。" +"定義引發例外佔位符的 :meth:`~object.__set__` 方法就足以讓它成為資料描述器。" #: ../../howto/descriptor.rst:555 msgid "Overview of descriptor invocation" -msgstr "" +msgstr "描述器呼叫概觀" #: ../../howto/descriptor.rst:557 msgid "" "A descriptor can be called directly with ``desc.__get__(obj)`` or " "``desc.__get__(None, cls)``." msgstr "" +"描述器可以直接使用 ``desc.__get__(obj)`` 或 ``desc.__get__(None, cls)`` 呼叫。" #: ../../howto/descriptor.rst:560 msgid "" From 2e006211a552c5bd84cf96c889743e7b1fa6875c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 16 Jul 2025 04:04:11 +0000 Subject: [PATCH 6/6] Add key invocation sections and complete substantial descriptor translation Co-authored-by: mattwang44 <24987826+mattwang44@users.noreply.github.com> --- howto/descriptor.po | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/howto/descriptor.po b/howto/descriptor.po index 054f1633b7..d826a210cf 100644 --- a/howto/descriptor.po +++ b/howto/descriptor.po @@ -519,7 +519,7 @@ msgstr "" #: ../../howto/descriptor.rst:267 msgid "The new class now logs access to both *name* and *age*:" -msgstr "" +msgstr "新類別現在記錄對 *name* 和 *age* 的存取:" #: ../../howto/descriptor.rst:275 msgid "" @@ -539,7 +539,7 @@ msgstr "" #: ../../howto/descriptor.rst:284 msgid "The two *Person* instances contain only the private names:" -msgstr "" +msgstr "兩個 *Person* 實例只包含私有名稱:" #: ../../howto/descriptor.rst:286 msgid "" @@ -1012,7 +1012,7 @@ msgstr "" #: ../../howto/descriptor.rst:573 msgid "Invocation from an instance" -msgstr "" +msgstr "從實例呼叫" #: ../../howto/descriptor.rst:575 msgid "" @@ -1021,18 +1021,22 @@ msgid "" "descriptors, then class variables, and lastly :meth:`~object.__getattr__` if " "it is provided." msgstr "" +"實例查找掃描命名空間鏈,給予資料描述器最高優先權,接著是實例變數,然後是非資料描述器," +"再來是類別變數,最後如果有提供的話是 :meth:`~object.__getattr__`。" #: ../../howto/descriptor.rst:580 msgid "" "If a descriptor is found for ``a.x``, then it is invoked with: " "``desc.__get__(a, type(a))``." msgstr "" +"如果為 ``a.x`` 找到描述器,則使用 ``desc.__get__(a, type(a))`` 呼叫它。" #: ../../howto/descriptor.rst:583 msgid "" "The logic for a dotted lookup is in :meth:`object.__getattribute__`. Here " "is a pure Python equivalent:" msgstr "" +"點查找的邏輯在 :meth:`object.__getattribute__` 中。這裡是純 Python 等價實作:" #: ../../howto/descriptor.rst:586 msgid "" @@ -1102,7 +1106,7 @@ msgstr "" #: ../../howto/descriptor.rst:776 msgid "Invocation from a class" -msgstr "" +msgstr "從類別呼叫" #: ../../howto/descriptor.rst:778 msgid "" @@ -1114,7 +1118,7 @@ msgstr "" #: ../../howto/descriptor.rst:783 msgid "If a descriptor is found, it is invoked with ``desc.__get__(None, A)``." -msgstr "" +msgstr "如果找到描述器,則使用 ``desc.__get__(None, A)`` 呼叫它。" #: ../../howto/descriptor.rst:785 msgid ""