diff --git a/library/pickle.po b/library/pickle.po index c512db8eb2..370cbe643d 100644 --- a/library/pickle.po +++ b/library/pickle.po @@ -2,6 +2,7 @@ # This file is distributed under the same license as the Python package. # # Translators: +# Skylull, 2024 msgid "" msgstr "" "Project-Id-Version: Python 3.13\n" @@ -25,6 +26,14 @@ msgstr ":mod:`!pickle` --- Python 物件序列化" msgid "**Source code:** :source:`Lib/pickle.py`" msgstr "**原始碼:**\\ :source:`Lib/pickle.py`" +# Skylull: 我對 `pickle` 的命名原因進行了簡單的搜尋,只找到一則討論 +# https://stackoverflow.com/questions/27324986/pickles-why-are-they-called- +# that +# 其中表示這名字很可能只是為了隨便找一個p開頭的單字、或原始開發人員的內部玩笑造成的約定俗成。也有人表示醃製黃瓜(pickle- +# ing)的目標就是保存和存放,所以取了這個名字。 +# 無論如何似乎沒有一個定論。 +# 因為不確定是否與醃漬的這個梗有關,我暫時選擇使用 `封裝` 與 `拆封` 作為譯文,大致保存那個把東西處裡後裝起來的感覺但又不至於太奇怪。 +# 唯一需要擔心的是是否有與 `encapsulation` (封裝,網路協定名詞)或 `package`(封包,網路協定名詞)搞混的可能。 #: ../../library/pickle.rst:22 msgid "" "The :mod:`pickle` module implements binary protocols for serializing and de-" @@ -36,10 +45,17 @@ msgid "" "\"serialization\", \"marshalling,\" [#]_ or \"flattening\"; however, to " "avoid confusion, the terms used here are \"pickling\" and \"unpickling\"." msgstr "" +":mod:`pickle` 模組實作的是一個在二進位層級上對 Python 物件進行序列化" +"(serialize)或去序列化(de-serialize)。*\"Pickling\"* 用於專門指摘將一個 " +"Python 物件轉換為一個二進位串流的過程,*\"unpickling\"* 則相反,指的是將一個" +"(來自 :term:`binary file` 或 :term:`bytes-like object` 的)二進位串流轉換回 " +"Python 物件的過程。Pickling(和 unpickling)的過程也可能被稱作 " +"\"serialization\", \"marshalling,\" [#]_ 或 \"flattening\"。不過,為了避免混" +"淆,本文件將統一稱作封裝(pickling)、拆封(unpickling)。" #: ../../library/pickle.rst:33 msgid "The ``pickle`` module **is not secure**. Only unpickle data you trust." -msgstr "" +msgstr "``pickle`` 模組**並不安全**,切記只拆封你信任的資料。" #: ../../library/pickle.rst:35 msgid "" @@ -47,18 +63,22 @@ msgid "" "arbitrary code during unpickling**. Never unpickle data that could have come " "from an untrusted source, or that could have been tampered with." msgstr "" +"pickle 封包是有可能被建立來在拆封的時候**執行任意惡意程式碼**的。絕對不要拆封" +"任何你無法信任其來源、或可能被修改過的 pickle 封包。" #: ../../library/pickle.rst:39 msgid "" "Consider signing data with :mod:`hmac` if you need to ensure that it has not " "been tampered with." -msgstr "" +msgstr "建議你可以使用 :mod:`hmac` 模組來簽署這個封包,以確保其未被修改過。" #: ../../library/pickle.rst:42 msgid "" "Safer serialization formats such as :mod:`json` may be more appropriate if " "you are processing untrusted data. See :ref:`comparison-with-json`." msgstr "" +"如果你在處理不受信任的資料,其他比較安全的序列化格式(例如 :mod:`json`)可能" +"會更適合。請參照 See :ref:`comparison-with-json` 的說明。" #: ../../library/pickle.rst:47 msgid "Relationship to other Python modules" @@ -75,12 +95,15 @@ msgid "" "Python objects. :mod:`marshal` exists primarily to support Python's :file:`." "pyc` files." msgstr "" +"Python 有另一個比較原始的序列化模組叫 :mod:`marshal`,不過其設計目的是為了支" +"援 Python 的預編譯功能 :file:`.pyc` 的運作。總地來說,請盡可能地使用 :mod:" +"`pickle`,沒事不要用 :mod:`marshal`。" #: ../../library/pickle.rst:57 msgid "" "The :mod:`pickle` module differs from :mod:`marshal` in several significant " "ways:" -msgstr "" +msgstr ":mod:`pickle` 和 :mod:`marshal` 有幾個明顯不同的地方:" #: ../../library/pickle.rst:59 msgid "" @@ -88,6 +111,8 @@ msgid "" "serialized, so that later references to the same object won't be serialized " "again. :mod:`marshal` doesn't do this." msgstr "" +":mod:`pickle` 會記住哪些物件已經被序列化過了,稍後再次參照到這個物件的時候才" +"不會進行重複的序列化。:mod:`marshal` 沒有這個功能。" #: ../../library/pickle.rst:63 msgid "" @@ -101,6 +126,11 @@ msgid "" "Shared objects remain shared, which can be very important for mutable " "objects." msgstr "" +"這對遞迴物件和物件共用都有影響。遞迴物件是指包含自我參照的物件。這些情況在 " +"marshal 模組中不會被處理,若嘗試使用 marshal 處理遞迴物件會導致 Python 直譯器" +"崩潰。物件共用發生在序列化的物件階層中、不同位置對同一物件有多個參照時。:mod:" +"`pickle` 只會儲存這個被參照的物件一次,並確保所有其他參照指向這個主要的版本。" +"共用的物件會保持共用,這對於可變(mutable)物件來說非常重要。" #: ../../library/pickle.rst:72 msgid "" @@ -109,6 +139,9 @@ msgid "" "transparently, however the class definition must be importable and live in " "the same module as when the object was stored." msgstr "" +":mod:`marshal` 無法序列化使用者自訂的類別和的實例。:mod:`pickle` 則可以讓使用" +"者儲存並還原自訂的類別實例,前提是儲存時該類別的定義存在於與要被儲存的物件所" +"在的模組中、且可以被引入(import)。" #: ../../library/pickle.rst:77 msgid "" @@ -122,6 +155,11 @@ msgid "" "differences if your data is crossing that unique breaking change language " "boundary." msgstr "" +":mod:`marshal` 序列化格式無法保證能在不同版本的 Python 之間移植。因為其主要的" +"作用是支援 :file:`.pyc` 檔案的運作,Python 的實作人員會在需要時實作無法前向相" +"容的序列化方式。但只要選擇了相容的 pickle 協定,且處理了 Python 2 和 Python " +"3 之間的資料類型差異,:mod:`pickle` 序列化協定能保證在不同 Python 版本間的相" +"容性。" #: ../../library/pickle.rst:90 msgid "Comparison with ``json``" @@ -132,6 +170,8 @@ msgid "" "There are fundamental differences between the pickle protocols and `JSON " "(JavaScript Object Notation) `_:" msgstr "" +"pickle 協定和 `JSON (JavaScript Object Notation) `_ 有一些" +"根本上的不同:" #: ../../library/pickle.rst:95 msgid "" @@ -139,17 +179,27 @@ msgid "" "of the time it is then encoded to ``utf-8``), while pickle is a binary " "serialization format;" msgstr "" +"JSON 以文字形式作為序列化的輸出(輸出 unicode 文字,但大多數又會被編碼為 " +"``UTF-8``),而 pickle 則是以二進位形式作為序列化的輸出;" #: ../../library/pickle.rst:99 msgid "JSON is human-readable, while pickle is not;" -msgstr "JSON 是人類可讀的,而 pickle 不是;" +msgstr "JSON 是人類可讀的,而 pickle 則無法;" #: ../../library/pickle.rst:101 msgid "" "JSON is interoperable and widely used outside of the Python ecosystem, while " "pickle is Python-specific;" msgstr "" +"JSON 具有高互通性(interoperability)且在 Python 以外的環境也被大量利用,但 " +"pickle 只能在 Python 內使用。" +# Skylull: [T] +# introspection -> 自省 +# introspection facilities -> 自省措施 +# https://zh.wikipedia.org/wiki/%E5%86%85%E7%9C%81_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6) +# https://book.pythontips.com/en/latest/object_introspection.html +# https://www.geeksforgeeks.org/code-introspection-in-python/ #: ../../library/pickle.rst:104 msgid "" "JSON, by default, can only represent a subset of the Python built-in types, " @@ -158,22 +208,29 @@ msgid "" "introspection facilities; complex cases can be tackled by implementing :ref:" "`specific object APIs `);" msgstr "" +"預設狀態下的 JSON 只能紀錄一小部份的 Python 內建型別,且無法紀錄自訂類別;但" +"透過 Python 的自省措施,pickle 可以紀錄絕大多數的 Python 型別(其他比較複雜的" +"狀況也可以透過實作 :ref:`specific object APIs ` 來解決);" #: ../../library/pickle.rst:110 msgid "" "Unlike pickle, deserializing untrusted JSON does not in itself create an " "arbitrary code execution vulnerability." msgstr "" +"去序列化不安全的 JSON 不會產生任意程式執行的風險,但去序列化不安全的 pickle " +"會。" #: ../../library/pickle.rst:114 msgid "" "The :mod:`json` module: a standard library module allowing JSON " "serialization and deserialization." msgstr "" +":mod:`json` module: 是標準函式庫的一部分,可讓使用者進行 JSON 的序列化與去序" +"列化。" #: ../../library/pickle.rst:121 msgid "Data stream format" -msgstr "" +msgstr "資料串流格式" #: ../../library/pickle.rst:126 msgid "" @@ -182,6 +239,9 @@ msgid "" "as JSON (which can't represent pointer sharing); however it means that non-" "Python programs may not be able to reconstruct pickled Python objects." msgstr "" +":mod:`pickle` 使用的資料格式是針對 Python 而設計的。好處是他不會受到外部標準" +"(像是 JSON,無法紀錄指標共用)的限制;不過這也代表其他不是 " +"Python 的程式可能無法重建 pickle 封裝的 Python 物件。" #: ../../library/pickle.rst:131 msgid "" @@ -189,6 +249,8 @@ msgid "" "representation. If you need optimal size characteristics, you can " "efficiently :doc:`compress ` pickled data." msgstr "" +"以預設設定來說,:mod:`pickle` 使用相對緊湊的二進位形式來儲存資料。如果你需要" +"盡可能地縮小檔案大小,你可以\\ :doc:`壓縮 `\\ 封裝的資料。" #: ../../library/pickle.rst:135 msgid "" @@ -196,6 +258,8 @@ msgid "" "generated by :mod:`pickle`. :mod:`pickletools` source code has extensive " "comments about opcodes used by pickle protocols." msgstr "" +":mod:`pickletools` 含有工具可分析 :mod:`pickle` 所產生的資料流。:mod:" +"`pickletools` 的源始碼詳細地記載了所有 pickle 協定的操作碼(opcode)。" #: ../../library/pickle.rst:139 msgid "" @@ -203,18 +267,21 @@ msgid "" "The higher the protocol used, the more recent the version of Python needed " "to read the pickle produced." msgstr "" +"截至目前為止,共有六種不同版本的協定可用於封裝 pickle。數字越大版本代表你需" +"要使用越新的 Python 版本來拆封相應的 pickle 封裝。" #: ../../library/pickle.rst:143 msgid "" "Protocol version 0 is the original \"human-readable\" protocol and is " "backwards compatible with earlier versions of Python." msgstr "" +"版本 0 的協定是最初「人類可讀」的版本,且可以向前支援早期版本的 Python。" #: ../../library/pickle.rst:146 msgid "" "Protocol version 1 is an old binary format which is also compatible with " "earlier versions of Python." -msgstr "" +msgstr "版本 1 的協定使用舊的二進位格式,一樣能向前支援早期版本的 Python。" #: ../../library/pickle.rst:149 msgid "" @@ -222,6 +289,9 @@ msgid "" "efficient pickling of :term:`new-style classes `. Refer " "to :pep:`307` for information about improvements brought by protocol 2." msgstr "" +"版本 2 的協定在 Python 2.3 中初次被引入。其可提供更高效率的 :term:`new-style " +"classes ` 封裝過程。請參閱 :pep:`307` 以了解版本 2 帶來的改" +"進。" #: ../../library/pickle.rst:153 msgid "" @@ -229,6 +299,8 @@ msgid "" "class:`bytes` objects and cannot be unpickled by Python 2.x. This was the " "default protocol in Python 3.0--3.7." msgstr "" +"版本 3 的協定在 Python 3.0 被新增。現在能支援封裝 :class:`bytes` 的物件且無法" +"被 2.x 版本的 Python 拆封。在 3.0~3.7 的 Python 預設使用 3 版協定。" #: ../../library/pickle.rst:157 msgid "" @@ -237,6 +309,9 @@ msgid "" "optimizations. It is the default protocol starting with Python 3.8. Refer " "to :pep:`3154` for information about improvements brought by protocol 4." msgstr "" +"版本 4 的協定在 Python 3.4 被新增。現在能支援超大物件的封裝、更多種型別的物件" +"以及針對部份資料格式的儲存進行最佳化。從 Python 3.8 起,預設使用第 4 版協定。" +"請參閱 :pep:`3154` 以了解第 4 版協定改進的細節。" #: ../../library/pickle.rst:163 msgid "" @@ -244,7 +319,16 @@ msgid "" "data and speedup for in-band data. Refer to :pep:`574` for information " "about improvements brought by protocol 5." msgstr "" +"版本 5 的協定在 Python 3.8 被新增。現在能支援帶外資料(Out-of-band data)並加" +"速帶內資料的處理速度。請參閱 :pep:`574` 以了解第 5 版協定改進的細節。" +# SkyLull: [T] +# persistent -> 持久 +# data persistent -> 資料持久化 +# https://zh.wikipedia.org/zh- +# tw/%E5%8F%AF%E6%8C%81%E4%B9%85%E5%8C%96%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84 +# https://1fly2sky.wordpress.com/2016/04/05/%E6%8C%81%E4%B9%85%E5%B1%A4data- +# persistence-layer/ #: ../../library/pickle.rst:168 msgid "" "Serialization is a more primitive notion than persistence; although :mod:" @@ -258,6 +342,13 @@ msgid "" "database. The :mod:`shelve` module provides a simple interface to pickle " "and unpickle objects on DBM-style database files." msgstr "" +"資料序列化是一個比資料持久化更早出現的概念;雖然 :mod:`pickle` 可以讀寫檔案物" +"件,但它並不處理命名持久物件的問題,也不處理對持久物件的並行存取、一個更棘手" +"的問題。:mod:`pickle` 模組可以將複雜物件轉換成位元組串流,也可以將位元組串流" +"轉換回具有相同原始內部結構的物件。對這些位元組串流最常見的處理方式是將它們寫" +"入檔案中,但也可以將它們透過網路傳送或儲存在一個資料庫中。:mod:`shelve` 模組" +"提供了一個簡單的介面來讓使用者在 DBM 風格的資料庫檔案中對物件進行封裝和拆封的" +"操作。" #: ../../library/pickle.rst:181 msgid "Module Interface" @@ -271,6 +362,10 @@ msgid "" "de-serialization, you can create a :class:`Pickler` or an :class:`Unpickler` " "object, respectively." msgstr "" +"想要序列化一個物件,你只需要呼叫 :func:`dumps` 函式。而當你想要去序列化一個資" +"料流時,你只需要呼叫 :func:`loads` 即可。不過,若你希望能各自對序列化和去序列" +"化的過程中有更多的掌控度,你可以自訂一個 :class:`Pickler` 或 :class:" +"`Unpickler` 物件。" #: ../../library/pickle.rst:188 msgid "The :mod:`pickle` module provides the following constants:" @@ -282,6 +377,9 @@ msgid "" "available. This value can be passed as a *protocol* value to functions :" "func:`dump` and :func:`dumps` as well as the :class:`Pickler` constructor." msgstr "" +"一個整數,表示可使用的最高\\ :ref:`協定版本 `。這個值可作" +"為 *protocol* 的數值傳給 :func:`dump` 和 :func:`dumps` 函式以及 :class:" +"`Pickler` 建構式。" #: ../../library/pickle.rst:200 msgid "" @@ -290,32 +388,39 @@ msgid "" "protocol is 4, first introduced in Python 3.4 and incompatible with previous " "versions." msgstr "" +"一個整數,指示用於序列化的預設\\ :ref:`協定版本 `。有可能小" +"於 :data:`HIGHEST_PROTOCOL`。目前的預設協定版本為 4,是在 Python 3.4 中首次引" +"入的,且與先前版本不相容。" #: ../../library/pickle.rst:207 msgid "The default protocol is 3." -msgstr "預設協定為 3。" +msgstr "預設協定版本為 3。" #: ../../library/pickle.rst:211 msgid "The default protocol is 4." -msgstr "預設協定為 4。" +msgstr "預設協定版本為 4。" #: ../../library/pickle.rst:213 msgid "" "The :mod:`pickle` module provides the following functions to make the " "pickling process more convenient:" -msgstr "" +msgstr ":mod:`pickle` 模組提供下列函式來簡化封裝的過程:" #: ../../library/pickle.rst:218 msgid "" "Write the pickled representation of the object *obj* to the open :term:`file " "object` *file*. This is equivalent to ``Pickler(file, protocol).dump(obj)``." msgstr "" +"將被封裝成 pickle 形式的物件 *obj* 寫入到已開啟的\\ :term:`file object` *file*。" +"這等效於\\ ``Pickler(file, protocol).dump(obj)``。" #: ../../library/pickle.rst:222 msgid "" "Arguments *file*, *protocol*, *fix_imports* and *buffer_callback* have the " "same meaning as in the :class:`Pickler` constructor." msgstr "" +"引數 *file*、*protocol*、*fix_imports* 和 *buffer_callback* 的意義與 :class:" +"`Pickler` 建構式中的相同。" #: ../../library/pickle.rst:225 ../../library/pickle.rst:236 #: ../../library/pickle.rst:328 @@ -327,12 +432,15 @@ msgid "" "Return the pickled representation of the object *obj* as a :class:`bytes` " "object, instead of writing it to a file." msgstr "" +"將被封裝為 pickle 形式的物件 *obj* 以 :class:`bytes` 類別回傳,而非寫入進檔案。" #: ../../library/pickle.rst:233 msgid "" "Arguments *protocol*, *fix_imports* and *buffer_callback* have the same " "meaning as in the :class:`Pickler` constructor." msgstr "" +"引數 *protocol*、*fix_imports* 和 *buffer_callback* 的意義和 :class:" +"`Pickler` 建構式中的相同。" #: ../../library/pickle.rst:241 msgid "" @@ -340,6 +448,8 @@ msgid "" "object` *file* and return the reconstituted object hierarchy specified " "therein. This is equivalent to ``Unpickler(file).load()``." msgstr "" +"從已開啟的 :term:`檔案物件 ` *file* 中讀取已序列化的物件,並傳回" +"其重建後的物件階層。這相當於呼叫 ``Unpickler(file).load()``。" #: ../../library/pickle.rst:245 ../../library/pickle.rst:260 msgid "" @@ -347,12 +457,16 @@ msgid "" "argument is needed. Bytes past the pickled representation of the object are " "ignored." msgstr "" +"模組會自動偵測 pickle 封包所使用的協定版本,所以無須另外指定。超出 pickle 封" +"包表示範圍的位元組將被忽略。" #: ../../library/pickle.rst:249 msgid "" "Arguments *file*, *fix_imports*, *encoding*, *errors*, *strict* and " "*buffers* have the same meaning as in the :class:`Unpickler` constructor." msgstr "" +"引數 *file*、*fix_imports*、*encoding*、*errors*、*strict* 和 *buffers* 的意" +"義和 :class:`Unpickler` 建構式中的相同。" #: ../../library/pickle.rst:252 ../../library/pickle.rst:267 #: ../../library/pickle.rst:433 @@ -364,40 +478,49 @@ msgid "" "Return the reconstituted object hierarchy of the pickled representation " "*data* of an object. *data* must be a :term:`bytes-like object`." msgstr "" +"回傳從 *data* 的 pickle 封包重建後的物件階層。*data* 必須是一個 :term:`bytes-" +"like object`。" #: ../../library/pickle.rst:264 msgid "" "Arguments *fix_imports*, *encoding*, *errors*, *strict* and *buffers* have " "the same meaning as in the :class:`Unpickler` constructor." msgstr "" +"引數 *fix_imports*、*encoding*、*errors*、*strict* 和 *buffers* 的意義與 :" +"class:`Unpickler` 建構式所用的相同。" #: ../../library/pickle.rst:271 msgid "The :mod:`pickle` module defines three exceptions:" -msgstr "" +msgstr ":mod:`pickle` 模組定義了以下三種例外:" #: ../../library/pickle.rst:275 msgid "" "Common base class for the other pickling exceptions. It inherits from :exc:" "`Exception`." msgstr "" +"繼承 :exc:`Exception` 類別。一個在封裝或拆封時遭遇其他例外時通用的基底類別。" #: ../../library/pickle.rst:280 msgid "" "Error raised when an unpicklable object is encountered by :class:`Pickler`. " "It inherits from :exc:`PickleError`." msgstr "" +"當 :class:`Pickler` 遭遇無法封裝物件時會引發的例外。繼承 :exc:`PickleError` " +"類別。" #: ../../library/pickle.rst:283 msgid "" "Refer to :ref:`pickle-picklable` to learn what kinds of objects can be " "pickled." -msgstr "" +msgstr "請參閱 :ref:`pickle-picklable` 以了解哪些物件是可以被封裝的。" #: ../../library/pickle.rst:288 msgid "" "Error raised when there is a problem unpickling an object, such as a data " "corruption or a security violation. It inherits from :exc:`PickleError`." msgstr "" +"拆封物件時遇到問題(如資料毀損或違反安全性原則等)所引發的意外。繼承自 :exc:" +"`PickleError` 類別。" #: ../../library/pickle.rst:291 msgid "" @@ -405,16 +528,20 @@ msgid "" "(but not necessarily limited to) AttributeError, EOFError, ImportError, and " "IndexError." msgstr "" +"拆封的時候還是可能會遭遇其他不在此列的例外(例如:AttributeError、EOFError、" +"ImportError、或 IndexError),請注意。" #: ../../library/pickle.rst:296 msgid "" "The :mod:`pickle` module exports three classes, :class:`Pickler`, :class:" "`Unpickler` and :class:`PickleBuffer`:" msgstr "" +"引入模組 :mod:`pickle` 時會帶來三個類別::class:`Pickler`、:class:" +"`Unpickler` 和 :class:`PickleBuffer`:" #: ../../library/pickle.rst:301 msgid "This takes a binary file for writing a pickle data stream." -msgstr "" +msgstr "接受一個用以寫入 pickle 資料流的二進位檔案。" #: ../../library/pickle.rst:303 msgid "" @@ -423,6 +550,9 @@ msgid "" "not specified, the default is :data:`DEFAULT_PROTOCOL`. If a negative " "number is specified, :data:`HIGHEST_PROTOCOL` is selected." msgstr "" +"可選引數 *protocol* 接受整數,用來要求封裝器(pickler)使用指定的協定;支援" +"從 0 版起到 :data:`HIGHEST_PROTOCOL` 版的協定。如未指定,則預設為 :data:" +"`DEFAULT_PROTOCOL`。若指定了負數,則視為選擇 :data:`HIGHEST_PROTOCOL`。" #: ../../library/pickle.rst:308 msgid "" @@ -431,6 +561,9 @@ msgid "" "class:`io.BytesIO` instance, or any other custom object that meets this " "interface." msgstr "" +"傳予引數 *file* 的物件必須支援可寫入單一位元組的 write() 方法。只要滿足此條" +"件,傳入的物件可以是一個硬碟上二進位檔案、一個 :class:`io.BytesIO` 實例或任何" +"其他滿足這個介面要求的物件。" #: ../../library/pickle.rst:313 msgid "" @@ -438,12 +571,21 @@ msgid "" "map the new Python 3 names to the old module names used in Python 2, so that " "the pickle data stream is readable with Python 2." msgstr "" +"若 *fix_imports* 設為 true 且 *protocol* 版本小於 3,本模組會嘗試將 Python 3 " +"的新模組名稱轉換為 Python 2 所支援的舊名,以讓 Python 2 能正確地讀取此資料" +"流。" +# SkyLull: 以下幾個關於 buffer_callback 的翻譯需要進一步的校對。何謂out-of-band? buffer view +# 應作何翻譯? +# out-of-band 目前參考 https://kb.synology.com/zh- +# tw/DSM/tutorial/Quick_Start_OOB_Management `帶外管理` 譯作 `帶外` #: ../../library/pickle.rst:317 msgid "" "If *buffer_callback* is ``None`` (the default), buffer views are serialized " "into *file* as part of the pickle stream." msgstr "" +"如果 *buffer_callback* 是 ``None`` (預設值),緩衝區的視圖會作為 pickle 封裝" +"串流的一部分被序列化進 *file* 中。" #: ../../library/pickle.rst:320 msgid "" @@ -452,22 +594,30 @@ msgid "" "``None``), the given buffer is :ref:`out-of-band `; otherwise " "the buffer is serialized in-band, i.e. inside the pickle stream." msgstr "" +"如果 *buffer_callback* 不是 ``None``,則它可以被多次呼叫並回傳一個緩衝區的視" +"圖。如果回呼函式回傳一個假值(例如 ``None``),則所給的緩衝區將被視為 :ref:`" +"帶外資料 `;否則,該緩衝區將被視為 pickle 串流的帶內資料被序列" +"化。" #: ../../library/pickle.rst:325 msgid "" "It is an error if *buffer_callback* is not ``None`` and *protocol* is " "``None`` or smaller than 5." msgstr "" +"如果 *buffer_callback* 不是 ``None`` 且 *protocol* 是 ``None`` 或小於 5 則會" +"報錯。" #: ../../library/pickle.rst:333 msgid "" "Write the pickled representation of *obj* to the open file object given in " "the constructor." -msgstr "" +msgstr "將已封裝(pickled)的 *obj* 寫入已在建構式中開啟的對應檔案。" #: ../../library/pickle.rst:338 msgid "Do nothing by default. This exists so a subclass can override it." msgstr "" +"預設不進行任何動作。這是一種抽象方法,用於讓後續繼承這個類別的物件可以覆寫本" +"方法函式。" #: ../../library/pickle.rst:340 msgid "" @@ -477,6 +627,10 @@ msgid "" "defined by :meth:`Unpickler.persistent_load`. Note that the value returned " "by :meth:`persistent_id` cannot itself have a persistent ID." msgstr "" +"如果 :meth:`persistent_id` 回傳 ``None``,則 *obj* 會照一般的方式進行封裝" +"(pickling)。若回傳其他值,則 :class:`Pickler` 會將該值作為 *obj* 的永久識別" +"碼回傳。此永久識別碼的意義應由 :meth:`Unpickler.persistent_load` 定義。請注" +"意 :meth:`persistent_id` 回傳的值本身不能擁有自己的永久識別碼。" #: ../../library/pickle.rst:346 ../../library/pickle.rst:451 msgid "See :ref:`pickle-persistent` for details and examples of uses." @@ -487,7 +641,15 @@ msgid "" "Add the default implementation of this method in the C implementation of :" "class:`!Pickler`." msgstr "" +"在 C 的 class:`!Pickler` 實作中的增加了這個方法的預設實作。" +# SkyLull: [T] +# dispatch table -> 調度表 +# https://zh.wiktionary.org/zh-hant/dispatch_table +# reduce -> 縮減 +# reduction function -> 縮減函式 +# 這個是指reduce()函式類型的運算,類似sql的aggregation類型運算,故參閱以下內文,譯為縮減 +# https://support.google.com/docs/answer/12657238?hl=zh-Hant #: ../../library/pickle.rst:354 msgid "" "A pickler object's dispatch table is a registry of *reduction functions* of " @@ -496,6 +658,10 @@ msgid "" "reduction function takes a single argument of the associated class and " "should conform to the same interface as a :meth:`~object.__reduce__` method." msgstr "" +"封裝器(pickler)物件含有的的調度表是一個 *縮減函式* (reduction function)的" +"註冊表,可以使用 :func:`copyreg.pickle` 來宣告這類縮減函式。它是一個以類別為" +"鍵、還原函式為值的映射表。縮減函式應準備接收一個對應類別的引數,並應遵循與 :" +"meth:`~object.__reduce__` 方法相同的介面。" #: ../../library/pickle.rst:362 msgid "" @@ -507,6 +673,11 @@ msgid "" "`dispatch_table` attribute then this will be used as the default dispatch " "table for instances of that class." msgstr "" +"預設情況下,封裝器(pickler)物件不會有 :attr:`dispatch_table` 屬性,而是會使" +"用由 :mod:`copyreg` 模組管理的全域調度表。不過,若要自訂某個封裝器(pickler)" +"物件的序列化行為,可以將 :attr:`dispatch_table` 屬性設置為類字典物件。另外," +"如果 :class:`Pickler` 的子類別具有 :attr:`dispatch_table` 屬性,那麼這個屬性" +"將作為該子類別實例的預設調度表。" #: ../../library/pickle.rst:371 msgid "See :ref:`pickle-dispatch` for usage examples." @@ -520,10 +691,15 @@ msgid "" "and can optionally return :data:`NotImplemented` to fallback on :attr:" "`dispatch_table`-registered reducers to pickle ``obj``." msgstr "" +"一個可以在 :class:`Pickler` 子類別中被定義的縮減器(reducer)。這個方法的優先" +"度高於任何其他 :attr:`分派表 ` 中的縮減器。他應該要有和 :" +"meth:`~object.__reduce__` 方法相同的函數界面,且可以可選地回傳 :data:" +"`NotImplemented` 以退回(fallback)使用 :attr:`分派表 ` 中登" +"錄的縮減方法來封裝 ``obj``。" #: ../../library/pickle.rst:383 msgid "For a detailed example, see :ref:`reducer_override`." -msgstr "" +msgstr "請查閱 :ref:`reducer_override` 來參考其他較詳細的範例。" #: ../../library/pickle.rst:389 msgid "" @@ -532,20 +708,23 @@ msgid "" "superfluous PUT opcodes. It should not be used with self-referential " "objects, doing otherwise will cause :class:`Pickler` to recurse infinitely." msgstr "" +"已棄用。如果設置為 true,將啟用快速模式。快速模式會停用備忘(memo),因此能透" +"過不產生多餘的 PUT 操作碼(OpCode)來加速封裝過程。它不應被用於自我參照物件," +"否則將導致 :class:`Pickler` 陷入無限遞迴。" #: ../../library/pickle.rst:395 msgid "Use :func:`pickletools.optimize` if you need more compact pickles." -msgstr "" +msgstr "使用 :func:`pickletools.optimize` 以獲得更緊湊的 pickle 輸出。" #: ../../library/pickle.rst:400 msgid "This takes a binary file for reading a pickle data stream." -msgstr "" +msgstr "這個物件接受一個二進位檔案 *file* 來從中讀取 pickle 資料流。" #: ../../library/pickle.rst:402 msgid "" "The protocol version of the pickle is detected automatically, so no protocol " "argument is needed." -msgstr "" +msgstr "協定版本號會被自動偵測,所以不需要在這邊手動輸入。" #: ../../library/pickle.rst:405 msgid "" @@ -556,6 +735,10 @@ msgid "" "binary reading, an :class:`io.BytesIO` object, or any other custom object " "that meets this interface." msgstr "" +"參數 *file* 必須擁有三個方法,分別是接受整數作為引數的 read() 方法、接受緩衝" +"區作為引數的 readinto() 方法以及不需要引數的 readline() 方法,如同在 :class:" +"`io.BufferedIOBase` 的介面一樣。因此,*file* 可以是一個以二進位讀取模式開啟的" +"檔案、一個 :class:`io.BytesIO` 物件、或任何符合此介面的自訂物件。" #: ../../library/pickle.rst:412 msgid "" @@ -570,6 +753,14 @@ msgid "" "datetime`, :class:`~datetime.date` and :class:`~datetime.time` pickled by " "Python 2." msgstr "" +"可選引數 *fix_imports*、*encoding* 和 *errors* 用來控制 Python 2 pickle 資料" +"的相容性支援。如果 *fix_imports* 為 true,則 pickle 模組會嘗試將舊的 Python " +"2 模組名稱映射到 Python 3 中使用的新名稱。*encoding* 和 *errors* 告訴 pickle " +"模組如何解碼由 Python 2 pickle 封裝的 8 位元字串實例;*encoding* 和 *errors* " +"預設分別為 'ASCII' 和 'strict'。*encoding* 可以設定為 'bytes' 以將這些 8 位元" +"字串實例讀為位元組物件。而由 Python 2 封裝的 NumPy 陣列、:class:`~datetime." +"datetime`、:class:`~datetime.date` 和 :class:`~datetime.time` 的實例則必須使" +"用 ``encoding='latin1'`` 來拆封。" #: ../../library/pickle.rst:423 msgid "" @@ -578,6 +769,9 @@ msgid "" "*buffer_callback* argument was ``None`` when a :class:`Pickler` was " "instantiated (or when :func:`dump` or :func:`dumps` was called)." msgstr "" +"如果 *buffers* 是 ``None``\\ (預設值),那麼去序列化所需的所有資料都必須已經" +"包含在 pickle 串流中。這意味著當初在建立對應的 :class:`Pickler` 時(或在呼" +"叫 :func:`dump` 或 :func:`dumps` 時)*buffer_callback* 引數必須為 ``None``。" #: ../../library/pickle.rst:428 msgid "" @@ -586,6 +780,10 @@ msgid "" "of-band ` buffer view. Such buffers have been given in order to " "the *buffer_callback* of a Pickler object." msgstr "" +"如果 *buffers* 不是 ``None``,則其應該是一個可疊代物件,內含數個支援緩衝區的" +"物件,並且每當 pickle 串流引用一個\\ :ref:`帶外 `\\ 緩衝區視圖時" +"將會被照順序消耗。這些緩衝資料當初建立時應已按照順序給定予 Pickler 物件中的 " +"*buffer_callback*。" #: ../../library/pickle.rst:438 msgid "" @@ -593,10 +791,12 @@ msgid "" "in the constructor, and return the reconstituted object hierarchy specified " "therein. Bytes past the pickled representation of the object are ignored." msgstr "" +"開啟先前被傳入建構子的檔案,從中讀取一個被 pickle 封裝的物件,並回傳重建完成" +"的物件階層。超過 pickle 表示範圍的位元組會被忽略。" #: ../../library/pickle.rst:445 msgid "Raise an :exc:`UnpicklingError` by default." -msgstr "" +msgstr "預設會拋出 :exc:`UnpicklingError` 例外。" #: ../../library/pickle.rst:447 msgid "" @@ -604,6 +804,8 @@ msgid "" "the persistent ID *pid*. If an invalid persistent ID is encountered, an :" "exc:`UnpicklingError` should be raised." msgstr "" +"若有定義 :meth:`persistent_load`,則其將回傳符合持久化識別碼 `pid` 的物件。如" +"果遭遇了無效的持久化識別碼,則會引發 :exc:`UnpicklingError`。" #: ../../library/pickle.rst:453 msgid "" @@ -618,6 +820,9 @@ msgid "" "unlike its name suggests, :meth:`find_class` is also used for finding " "functions." msgstr "" +"如有需要將引入 *module* ,並從中返回名為 *name* 的物件,這裡的 *module* 和 " +"*name* 引數接受的輸入是 :class:`str` 物件。注意,雖然名稱上看起來不像,但 :" +"meth:`find_class` 亦可被用於尋找其他函式。" #: ../../library/pickle.rst:464 msgid "" @@ -625,6 +830,8 @@ msgid "" "how they can be loaded, potentially reducing security risks. Refer to :ref:" "`pickle-restrict` for details." msgstr "" +"子類別可以覆寫此方法以控制可以載入哪些類型的物件、以及如何載入它們,從而潛在" +"地降低安全性風險。詳情請參考\\ :ref:`pickle-restrict`。" #: ../../library/pickle.rst:468 msgid "" @@ -634,12 +841,18 @@ msgstr "" "引發一個附帶引數 ``module``、``name`` 的\\ :ref:`稽核事件 ` " "``pickle.find_class``。" +# SkyLull: [T] +# 參見 #729 +# wrapper -> 包裝器 #: ../../library/pickle.rst:472 msgid "" "A wrapper for a buffer representing picklable data. *buffer* must be a :ref:" "`buffer-providing ` object, such as a :term:`bytes-like " "object` or a N-dimensional array." msgstr "" +"一個表示了含有可封裝數據緩衝區的包裝函數(wrapper function)。*buffer* 必須是" +"一個 :ref:`提供緩衝區 ` 的物件,例如一個 :term:`類位元組物件 " +"` 或 N 維陣列。" #: ../../library/pickle.rst:476 msgid "" @@ -647,6 +860,8 @@ msgid "" "to pass it to other APIs expecting a buffer-providing object, such as :class:" "`memoryview`." msgstr "" +":class:`PickleBuffer` 本身就是一個提供緩衝區的物件,所以是能夠將其提供給其它" +"「預期收到含有緩衝物件的 API」的,比如 :class:`memoryview`。" #: ../../library/pickle.rst:480 msgid "" @@ -654,7 +869,13 @@ msgid "" "or higher. They are eligible for :ref:`out-of-band serialization `." msgstr "" +":class:`PickleBuffer` 物件僅能由 5 版或以上的 pickle 協定進行封裝。該物件亦能" +"被作為帶外資料來進行\\ :ref:`帶外資料序列化 `" +# SkyLull: oh... 好多術語... +# format B: https://learn.microsoft.com/zh-tw/dotnet/standard/base- +# types/standard-numeric-format-strings#BFormatString +# C-contiguous, Fortran-contiguous: https://stackoverflow.com/a/26999092 #: ../../library/pickle.rst:488 msgid "" "Return a :class:`memoryview` of the memory area underlying this buffer. The " @@ -662,53 +883,63 @@ msgid "" "``B`` (unsigned bytes). :exc:`BufferError` is raised if the buffer is " "neither C- nor Fortran-contiguous." msgstr "" +"返回此緩衝區底層記憶體區域的 :class:`memoryview`。被返回的物件是一個(在 C 語" +"言的 formatter 格式中)以 ``B`` (unsigned bytes) 二進位格式儲存、一維且列連續" +"(C-contiguous)的 memoryview。如果緩衝區既不是列連續(C-contiguous)也不是行" +"連續(Fortran-contiguous)的,則會引發 :exc:`BufferError`。" #: ../../library/pickle.rst:495 msgid "Release the underlying buffer exposed by the PickleBuffer object." -msgstr "" +msgstr "釋放 PickleBuffer 物件現正曝光中的緩衝區。" #: ../../library/pickle.rst:501 msgid "What can be pickled and unpickled?" -msgstr "" +msgstr "哪些物件能或不能被封裝、拆封?" #: ../../library/pickle.rst:503 msgid "The following types can be pickled:" -msgstr "" +msgstr "下列型別可以被封裝:" #: ../../library/pickle.rst:505 msgid "" "built-in constants (``None``, ``True``, ``False``, ``Ellipsis``, and :data:" "`NotImplemented`);" msgstr "" +"內建常數(``None``、``True``、``False``、``Ellipsis`` 和 :data:" +"`NotImplemented`);" #: ../../library/pickle.rst:508 msgid "integers, floating-point numbers, complex numbers;" -msgstr "" +msgstr "整數、浮點數和複數;" #: ../../library/pickle.rst:510 msgid "strings, bytes, bytearrays;" -msgstr "" +msgstr "字串、位元組物件、位元組陣列;" #: ../../library/pickle.rst:512 msgid "" "tuples, lists, sets, and dictionaries containing only picklable objects;" -msgstr "" +msgstr "元組(tuple)、串列(list)、集合(set)和僅含有可封裝物件的字典;" #: ../../library/pickle.rst:514 msgid "" "functions (built-in and user-defined) accessible from the top level of a " "module (using :keyword:`def`, not :keyword:`lambda`);" msgstr "" +"在模組最表面的層級就能被存取的函式(內建或自訂的皆可,不過僅限使用 :keyword:" +"`def` 定義的函式,:keyword:`lambda` 函式不適用);" #: ../../library/pickle.rst:517 msgid "classes accessible from the top level of a module;" -msgstr "" +msgstr "在模組最表面的層級就能被存取的類別;" #: ../../library/pickle.rst:519 msgid "" "instances of such classes whose the result of calling :meth:`~object." "__getstate__` is picklable (see section :ref:`pickle-inst` for details)." msgstr "" +"實例,只要在呼叫了 :meth:`~object.__getstate__` 後其回傳值全都是可封裝物件。" +"(詳情請參閱 :ref:`pickle-inst`)。" #: ../../library/pickle.rst:522 msgid "" @@ -719,7 +950,14 @@ msgid "" "`RecursionError` will be raised in this case. You can carefully raise this " "limit with :func:`sys.setrecursionlimit`." msgstr "" +"嘗試封裝無法封裝的物件會引發 :exc:`PicklingError` 例外;注意當這種情況發生" +"時,可能已經有未知數量的位元組已被寫入到檔案。嘗試封裝深度遞迴的資料結構可能" +"會導致其超出最大遞迴深度,在這種情況下會引發 :exc:`RecursionError` 例外。你可" +"以(小心地)使用 :func:`sys.setrecursionlimit` 來提高此上限。" +# SkyLull: [T] +# 請見官方術語表 +# qualified name -> 限定名稱 #: ../../library/pickle.rst:529 msgid "" "Note that functions (built-in and user-defined) are pickled by fully :term:" @@ -730,6 +968,11 @@ msgid "" "environment, and the module must contain the named object, otherwise an " "exception will be raised. [#]_" msgstr "" +"請注意,函式(內建及自訂兩者皆是)是依據完整的 :term:`限定名稱 ` 來封裝,而非依其值。[#]_ 這意味著封裝時只有函式名稱、所屬的模組和所屬" +"的類別名稱會被封裝。函式本身的程式碼及其附帶的任何屬性均不會被封裝。因此,在" +"拆封該物件的環境中,定義此函式的模組必須可被引入,且該模組必須包含具此命名之" +"物件,否則將引發例外。 [#]_" #: ../../library/pickle.rst:536 msgid "" @@ -738,6 +981,9 @@ msgid "" "class's code or data is pickled, so in the following example the class " "attribute ``attr`` is not restored in the unpickling environment::" msgstr "" +"同樣情況,類別是依照其完整限定名稱來進行封裝,因此在進行拆封的環境中會具有同" +"上的限制。類別中的程式碼或資料皆不會被封裝,因此在以下範例中,注意到類別屬性 " +"``attr`` 在拆封的環境中不會被還原::" #: ../../library/pickle.rst:541 msgid "" @@ -755,7 +1001,7 @@ msgstr "" msgid "" "These restrictions are why picklable functions and classes must be defined " "at the top level of a module." -msgstr "" +msgstr "這些限制就是可封裝的函式和類別必須被定義在模組頂層的原因。" #: ../../library/pickle.rst:549 msgid "" @@ -768,16 +1014,23 @@ msgid "" "that suitable conversions can be made by the class's :meth:`~object." "__setstate__` method." msgstr "" +"同樣地,當類別實例被封裝時,它所屬類別具有的程式碼和資料不會被一起封裝。只有" +"實例資料本身會被封裝。這是有意而為的,因為如此你才可以在類別中修正錯誤或新增" +"其他方法,且於此同時仍能夠載入使用較早期版本的類別所建立的物件實例。如果您預" +"計將有長期存在的物件、且該物件將經歷許多版本的更替,你可以在物件中存放一個版" +"本號,以便未來能透過 :meth:`~object.__setstate__` 方法來進行適當的版本轉換。" #: ../../library/pickle.rst:561 msgid "Pickling Class Instances" -msgstr "" +msgstr "Pickling 類別實例" #: ../../library/pickle.rst:565 msgid "" "In this section, we describe the general mechanisms available to you to " "define, customize, and control how class instances are pickled and unpickled." msgstr "" +"在這一個章節,我們會講述如何封裝或拆封一個物件實例的相關機制,以方便你進行自" +"訂。" #: ../../library/pickle.rst:568 msgid "" @@ -788,6 +1041,10 @@ msgid "" "creates an uninitialized instance and then restores the saved attributes. " "The following code shows an implementation of this behaviour::" msgstr "" +"大部分的實例不需要額外的程式碼就已經是可封裝的了。在這樣的預設狀況中,pickle " +"模組透過自省機制來取得類別及其實例的屬性。當類別實例被拆封時,其 :meth:" +"`~object.__init__` 方法通常*不會*被呼叫。預設行為首先會建立一個未初始化的實" +"例,然後還原紀錄中的屬性。以下程式碼的實作展示了前述行為::" #: ../../library/pickle.rst:575 msgid "" @@ -812,6 +1069,7 @@ msgid "" "Classes can alter the default behaviour by providing one or several special " "methods:" msgstr "" +"被封裝的目標類別可以提供一個或數個下列特殊方法來改變 pickle 的預設行為:" #: ../../library/pickle.rst:588 msgid "" @@ -822,6 +1080,10 @@ msgid "" "dictionary of named arguments for constructing the object. Those will be " "passed to the :meth:`__new__` method upon unpickling." msgstr "" +"在第 2 版協定或更新的版本中,有實作 :meth:`__getnewargs_ex__` 方法的類別,可" +"以決定在拆封時要傳遞給 :meth:`__new__` 方法的值。該方法必須回傳一個 ``(args, " +"kwargs)`` 的組合,其中 *args* 是一個位置引數的元組(tuple),*kwargs* 是一個" +"用於建構物件的命名引數字典。這些資訊將在拆封時傳遞給 :meth:`__new__` 方法。" #: ../../library/pickle.rst:596 msgid "" @@ -829,10 +1091,12 @@ msgid "" "requires keyword-only arguments. Otherwise, it is recommended for " "compatibility to implement :meth:`__getnewargs__`." msgstr "" +"如果目標類別的方法 :meth:`__new__` 需要僅限關鍵字的參數時,你應該實作此方法。" +"否則,為了提高相容性,建議你改為實作 :meth:`__getnewargs__`。" #: ../../library/pickle.rst:600 msgid ":meth:`__getnewargs_ex__` is now used in protocols 2 and 3." -msgstr "" +msgstr "在第 2、3 版的協定中現在改為使用 :meth:`__getnewargs_ex__`。" #: ../../library/pickle.rst:606 msgid "" @@ -840,18 +1104,24 @@ msgid "" "supports only positional arguments. It must return a tuple of arguments " "``args`` which will be passed to the :meth:`__new__` method upon unpickling." msgstr "" +"此方法與 :meth:`__getnewargs_ex__` 的目的一樣,但僅支援位置參數。它必須回傳一" +"個由傳入引數所組成的元組(tuple)``args``,這些引數會在拆封時傳遞給 :meth:" +"`__new__` 方法。" #: ../../library/pickle.rst:610 msgid "" ":meth:`__getnewargs__` will not be called if :meth:`__getnewargs_ex__` is " "defined." msgstr "" +"當有定義 :meth:`__getnewargs_ex__` 的時候便不會呼叫 :meth:`__getnewargs__`。" #: ../../library/pickle.rst:613 msgid "" "Before Python 3.6, :meth:`__getnewargs__` was called instead of :meth:" "`__getnewargs_ex__` in protocols 2 and 3." msgstr "" +"在 Python 3.6 之前、版本 2 和版本 3 的協定中,會呼叫 :meth:`__getnewargs__` " +"而非 :meth:`__getnewargs_ex__`。" #: ../../library/pickle.rst:620 msgid "" @@ -860,18 +1130,25 @@ msgid "" "pickled as the contents for the instance, instead of a default state. There " "are several cases:" msgstr "" +"目標類別可以透過覆寫方法 :meth:`__getstate__` 進一步影響其實例被封裝的方式。" +"封裝時,呼叫該方法所返回的物件將作為該實例的內容被封裝、而非一個預設狀態。以" +"下列出幾種預設狀態:" #: ../../library/pickle.rst:625 msgid "" "For a class that has no instance :attr:`~object.__dict__` and no :attr:" "`~object.__slots__`, the default state is ``None``." msgstr "" +"沒有 :attr:`~object.__dict__` 和 :attr:`~object.__slots__` 實例的類別,其預設" +"狀態為 ``None``。" #: ../../library/pickle.rst:628 msgid "" "For a class that has an instance :attr:`~object.__dict__` and no :attr:" "`~object.__slots__`, the default state is ``self.__dict__``." msgstr "" +"有 :attr:`~object.__dict__` 實例、但沒有 :attr:`~object.__slots__` 實例的類" +"別,其預設狀態為 ``self.__dict__``。" #: ../../library/pickle.rst:631 msgid "" @@ -880,6 +1157,10 @@ msgid "" "``self.__dict__``, and a dictionary mapping slot names to slot values. Only " "slots that have a value are included in the latter." msgstr "" +"有 :attr:`~object.__dict__` 和 :attr:`~object.__slots__` 實例的類別,其預設狀" +"態是一個含有兩個字典的元組(tuple),該二字典分別為 ``self.__dict__`` 本身," +"和紀錄欄位(slot)名稱和值對應關係的字典(只有含有值的欄位(slot)會被紀錄其" +"中)。" #: ../../library/pickle.rst:637 msgid "" @@ -888,12 +1169,15 @@ msgid "" "``None`` and whose second item is a dictionary mapping slot names to slot " "values described in the previous bullet." msgstr "" +"沒有 :attr:`~object.__dict__` 但有 :attr:`~object.__slots__` 實例的類別,其預" +"設狀態是一個二元組(tuple),元組中的第一個值是 ``None``,第二個值則是紀錄欄" +"位(slot)名稱和值對應關係的字典(與前一項提到的字典是同一個)。" #: ../../library/pickle.rst:642 msgid "" "Added the default implementation of the ``__getstate__()`` method in the :" "class:`object` class." -msgstr "" +msgstr "在 :class:`object` 類別中增加預設的 ``__getstate__()`` 實作。" #: ../../library/pickle.rst:649 msgid "" @@ -902,12 +1186,17 @@ msgid "" "state object to be a dictionary. Otherwise, the pickled state must be a " "dictionary and its items are assigned to the new instance's dictionary." msgstr "" +"在拆封時,如果類別定義了 :meth:`__setstate__`,則會使用拆封後的狀態呼叫它。在" +"這種情況下,紀錄狀態的物件不需要是字典(dictionary)。否則,封裝時的狀態紀錄" +"必須是一個字典,其紀錄的項目將被賦值給新實例的字典。" #: ../../library/pickle.rst:656 msgid "" "If :meth:`__reduce__` returns a state with value ``None`` at pickling, the :" "meth:`__setstate__` method will not be called upon unpickling." msgstr "" +"如果 :meth:`__reduce__` 在封裝時返回了 ``None`` 狀態,則拆封時就不會去呼叫 :" +"meth:`__setstate__`。" #: ../../library/pickle.rst:660 msgid "" @@ -915,6 +1204,8 @@ msgid "" "use the methods :meth:`~object.__getstate__` and :meth:`~object." "__setstate__`." msgstr "" +"參閱 :ref:`pickle-state` 以了解 :meth:`~object.__getstate__` 和 :meth:" +"`~object.__setstate__` 的使用方法。" #: ../../library/pickle.rst:665 msgid "" @@ -925,6 +1216,10 @@ msgid "" "such an invariant, as :meth:`~object.__init__` is not called when unpickling " "an instance." msgstr "" +"在拆封時,某些方法如 :meth:`~object.__getattr__`、:meth:`~object." +"__getattribute__` 或 :meth:`~object.__setattr__` 可能會在建立實例時被呼叫。如" +"果這些方法依賴了某些實例內部的不變性,則應實作 :meth:`~object.__new__` 以建立" +"此不變性,因為在拆封實例時不會呼叫 :meth:`~object.__init__`。" #: ../../library/pickle.rst:674 msgid "" @@ -934,6 +1229,9 @@ msgid "" "unified interface for retrieving the data necessary for pickling and copying " "objects. [#]_" msgstr "" +"如稍後所演示,pickle 並不直接使用上述方法。這些方法實際上是實作了 :meth:" +"`~object.__reduce__` 特殊方法的拷貝協定(copy protocol)。拷貝協定提供了統一" +"的介面,以檢索進行封裝及複製物件時所需的資料。 [#]_" #: ../../library/pickle.rst:680 msgid "" @@ -944,6 +1242,11 @@ msgid "" "We will show, however, cases where using :meth:`!__reduce__` is the only " "option or leads to more efficient pickling or both." msgstr "" +"直接在類別中實作 :meth:`~object.__reduce__` 雖然功能強大但卻容易導致出錯。因" +"此,設計類別者應盡可能使用高階介面(例如,:meth:`~object." +"__getnewargs_ex__`、:meth:`~object.__getstate__` 和 :meth:`~object." +"__setstate__`)。不過,我們也將展示一些特例狀況,在這些狀況中,使用 :meth:`!" +"__reduce__` 可能是唯一的選擇、是更有效率的封裝方法或二者兼備。" #: ../../library/pickle.rst:689 msgid "" @@ -951,6 +1254,8 @@ msgid "" "method takes no argument and shall return either a string or preferably a " "tuple (the returned object is often referred to as the \"reduce value\")." msgstr "" +"目前的介面定義如下。 :meth:`__reduce__` 方法不接受引數,且應回傳一個字串或一" +"個元組(元組一般而言是較佳的選擇;所回傳的物件通常稱為「縮減值」)。" #: ../../library/pickle.rst:693 msgid "" @@ -959,6 +1264,9 @@ msgid "" "module; the pickle module searches the module namespace to determine the " "object's module. This behaviour is typically useful for singletons." msgstr "" +"如果回傳的是字串,該字串應被解讀為一個全域變數的名稱。它應是該物件相對其所在" +"模組的本地名稱;pickle 模組會在模組命名空間中尋找,以確定該物件所在的模組。這" +"種行為通常對於單例物件特別有用。" #: ../../library/pickle.rst:698 msgid "" @@ -966,18 +1274,22 @@ msgid "" "Optional items can either be omitted, or ``None`` can be provided as their " "value. The semantics of each item are in order:" msgstr "" +"當返回一個元組時,其長度必須介於兩至六項元素之間。可選項可以被省略,或者其值" +"可以被設為 ``None``。各項物件的語意依序為:" #: ../../library/pickle.rst:704 msgid "" "A callable object that will be called to create the initial version of the " "object." -msgstr "" +msgstr "一個將會被呼叫來創建初始版本物件的可呼叫物件。" #: ../../library/pickle.rst:707 msgid "" "A tuple of arguments for the callable object. An empty tuple must be given " "if the callable does not accept any argument." msgstr "" +"一個用於傳遞引數給前述物件的元組。如果前述物件不接受引數輸入,則你仍應在這裡" +"給定一個空元組。" #: ../../library/pickle.rst:710 msgid "" @@ -986,7 +1298,12 @@ msgid "" "method then, the value must be a dictionary and it will be added to the " "object's :attr:`~object.__dict__` attribute." msgstr "" +"可選項。物件狀態。如前所述,會被傳遞給該物件的 :meth:`__setstate__` 方法。如" +"果該物件沒有實作此方法,則本值必須是一個字典,且其將會被新增到物件的 :attr:" +"`~object.__dict__` 屬性中。" +# SkyLull: [T] +# signature: https://jo-jo.medium.com/c-c-%E5%B9%BC%E5%B9%BC%E7%8F%AD-%E7%B0%BD%E7%AB%A0signature-fa9b04e1a3e2 #: ../../library/pickle.rst:715 msgid "" "Optionally, an iterator (and not a sequence) yielding successive items. " @@ -998,6 +1315,12 @@ msgid "" "which pickle protocol version is used as well as the number of items to " "append, so both must be supported.)" msgstr "" +"可選項。一個用來提供連續項目的疊代器(而非序列)。這些項目將個別透過 ``obj." +"append(item)`` 方法或成批次地透過 ``obj.extend(list_of_items)`` 方法被附加到" +"物件中。主要用於串列(list)子類別,但只要其他類別具有相應的 :ref:`append 和 " +"extend 方法 `\\ 以及相同的函式簽章(signature)就也可以使用。 " +"(是否會調用 :meth:`!append` 或 :meth:`!extend` 方法將取決於所選用的 " +"pickle 協定版本以及要附加的項目數量,因此必須同時支援這兩種方法。)" #: ../../library/pickle.rst:725 msgid "" @@ -1006,6 +1329,9 @@ msgid "" "value``. This is primarily used for dictionary subclasses, but may be used " "by other classes as long as they implement :meth:`__setitem__`." msgstr "" +"可選項。一個產生連續鍵值對的疊代器(不是序列)。這些項目將以 ``obj[key] = " +"value`` 方式被儲存到物件中。主要用於字典(dictionary)子類別,但只要有實現" +"了 :meth:`__setitem__` 的其他類別也可以使用。" #: ../../library/pickle.rst:730 msgid "" @@ -1015,10 +1341,14 @@ msgid "" "method. If not ``None``, this callable will have priority over ``obj``'s :" "meth:`__setstate__`." msgstr "" +"可選項。一個具有 ``(obj, state)`` 函式簽章(signature)的可呼叫物件。該物件允" +"許使用者以可編寫的邏輯,而不是物件 ``obj`` 預設的 :meth:`__setstate__` 靜態方" +"法去控制特定物件的狀態更新方式。如果這個物件不是 ``None``,這個物件的呼叫優先" +"權將優於物件 ``obj`` 的 :meth:`__setstate__`。" #: ../../library/pickle.rst:736 msgid "The optional sixth tuple item, ``(obj, state)``, was added." -msgstr "" +msgstr "加入第六個可選項(一個 ``(obj, state)`` 元組)。" #: ../../library/pickle.rst:742 msgid "" @@ -1029,10 +1359,14 @@ msgid "" "a synonym for the extended version. The main use for this method is to " "provide backwards-compatible reduce values for older Python releases." msgstr "" +"另外,你也可以定義一個 :meth:`__reduce_ex__` 方法。唯一的不同的地方是此方法只" +"接受協定版本(整數)作為參數。當有定義本方法時,pickle 會優先調用它而不是 :" +"meth:`__reduce__` 。此外,呼叫 :meth:`__reduce__` 時也會自動變成呼叫這個變體" +"版本。此方法主要是為了向後相容的舊的 Python 版本而存在。" #: ../../library/pickle.rst:754 msgid "Persistence of External Objects" -msgstr "" +msgstr "外部物件持久化" #: ../../library/pickle.rst:760 msgid "" @@ -1042,6 +1376,10 @@ msgid "" "of alphanumeric characters (for protocol 0) [#]_ or just an arbitrary object " "(for any newer protocol)." msgstr "" +"為了方便物件持久化,:mod:`pickle` 模組支援對被封裝資料串流以外的物件參照。被" +"參照的物件是透過一個持久化 ID 來參照的,這個 ID 應該要是字母數字字元" +"(alphanumeric)組成的字串(協定 0) [#]_ 或者是任意的物件(任何較新的協" +"定)。" #: ../../library/pickle.rst:766 msgid "" @@ -1050,6 +1388,9 @@ msgid "" "pickler and unpickler, :meth:`~Pickler.persistent_id` and :meth:`~Unpickler." "persistent_load` respectively." msgstr "" +":mod:`pickle` 沒有定義要如何解決或分派這個持久化 ID 的問題;故其處理方式有賴" +"使用者自行定義在封裝器(pickler)以及拆封器(unpickler)中。方法的名稱各自" +"為 :meth:`~Pickler.persistent_id` 和 :meth:`~Unpickler.persistent_load`。" #: ../../library/pickle.rst:771 msgid "" @@ -1061,6 +1402,11 @@ msgid "" "object, along with a marker so that the unpickler will recognize it as a " "persistent ID." msgstr "" +"要封裝具有外部持久化 ID 的物件,封裝器(pickler)必須擁有一個自訂的方法 :" +"meth:`~Pickler.persistent_id`,這個方法將接收一個物件作為參數,並回傳 `None` " +"或該物件的持久化 ID。當回傳 `None` 時,封裝器會正常地封裝該物件。當回傳一個持" +"久化 ID 字串時,封裝器會封裝該物件並加上一個標記,讓拆封器(unpikler)能識別" +"它是一個持久化 ID。" #: ../../library/pickle.rst:778 msgid "" @@ -1068,12 +1414,15 @@ msgid "" "`~Unpickler.persistent_load` method that takes a persistent ID object and " "returns the referenced object." msgstr "" +"要拆封外部物件,拆封器(unpickler)必須有一個自訂的 :meth:`~Unpickler." +"persistent_load` 方法,該方法應接受一個持久化 ID 物件,並回傳相對應的物件。" #: ../../library/pickle.rst:782 msgid "" "Here is a comprehensive example presenting how persistent ID can be used to " "pickle external objects by reference." msgstr "" +"以下是一個完整的範例,用以說明如何使用持久化 ID 來封裝具外部參照的物件。" #: ../../library/pickle.rst:785 msgid "" @@ -1172,10 +1521,96 @@ msgid "" "if __name__ == '__main__':\n" " main()\n" msgstr "" +"# 展示如何使用持久化 ID 來封裝外部物件的簡單範例\n" +"\n" +"import pickle\n" +"import sqlite3\n" +"from collections import namedtuple\n" +"\n" +"# 代表資料庫中紀錄的一個簡易類別\n" +"MemoRecord = namedtuple(\"MemoRecord\", \"key, task\")\n" +"\n" +"class DBPickler(pickle.Pickler):\n" +"\n" +" def persistent_id(self, obj):\n" +" # 我們派發出一個持久 ID,而不是像一般類別實例那樣封裝 MemoRecord。\n" +" if isinstance(obj, MemoRecord):\n" +" # 我們的持久 ID 就是一個元組,裡面包含一個標籤和一個鍵,指向資料" +"庫中的特定紀錄。\n" +" return (\"MemoRecord\", obj.key)\n" +" else:\n" +" # 如果 obj 沒有持久 ID,則返回 None。這表示 obj 像平常那樣封裝即" +"可。\n" +" return None\n" +"\n" +"\n" +"class DBUnpickler(pickle.Unpickler):\n" +"\n" +" def __init__(self, file, connection):\n" +" super().__init__(file)\n" +" self.connection = connection\n" +"\n" +" def persistent_load(self, pid):\n" +" # 每當遇到持久 ID 時,此方法都會被呼叫。\n" +" # pid 是 DBPickler 所回傳的元組。\n" +" cursor = self.connection.cursor()\n" +" type_tag, key_id = pid\n" +" if type_tag == \"MemoRecord\":\n" +" # 從資料庫中抓取所引用的紀錄並返回。\n" +" cursor.execute(\"SELECT * FROM memos WHERE key=?\", " +"(str(key_id),))\n" +" key, task = cursor.fetchone()\n" +" return MemoRecord(key, task)\n" +" else:\n" +" # 如果無法返回正確的物件,則必須拋出錯誤。\n" +" # 否則 unpickler 會誤認為 None 是持久 ID 所引用的物件。\n" +" raise pickle.UnpicklingError(\"unsupported persistent object\")\n" +"\n" +"\n" +"def main():\n" +" import io\n" +" import pprint\n" +"\n" +" # 初始化資料庫。\n" +" conn = sqlite3.connect(\":memory:\")\n" +" cursor = conn.cursor()\n" +" cursor.execute(\"CREATE TABLE memos(key INTEGER PRIMARY KEY, task " +"TEXT)\")\n" +" tasks = (\n" +" 'give food to fish',\n" +" 'prepare group meeting',\n" +" 'fight with a zebra',\n" +" )\n" +" for task in tasks:\n" +" cursor.execute(\"INSERT INTO memos VALUES(NULL, ?)\", (task,))\n" +"\n" +" # 抓取要封裝的紀錄。\n" +" cursor.execute(\"SELECT * FROM memos\")\n" +" memos = [MemoRecord(key, task) for key, task in cursor]\n" +" # 使用我們自訂的 DBPickler 來保存紀錄。\n" +" file = io.BytesIO()\n" +" DBPickler(file).dump(memos)\n" +"\n" +" print(\"被封裝的紀錄:\")\n" +" pprint.pprint(memos)\n" +"\n" +" # 更新一筆紀錄(測試用)。\n" +" cursor.execute(\"UPDATE memos SET task='learn italian' WHERE key=1\")\n" +"\n" +" # 從 pickle 資料流中載入紀錄。\n" +" file.seek(0)\n" +" memos = DBUnpickler(file, conn).load()\n" +"\n" +" print(\"已拆封的紀錄:\")\n" +" pprint.pprint(memos)\n" +"\n" +"\n" +"if __name__ == '__main__':\n" +" main()\n" #: ../../library/pickle.rst:790 msgid "Dispatch Tables" -msgstr "" +msgstr "調度表" #: ../../library/pickle.rst:792 msgid "" @@ -1183,6 +1618,8 @@ msgid "" "other code which depends on pickling, then one can create a pickler with a " "private dispatch table." msgstr "" +"如果你希望在不干擾其他物件正常封裝的前提下建立一個針對特定物件的封裝器,你可" +"建立一個有私密調度表的封裝器。" #: ../../library/pickle.rst:796 msgid "" @@ -1190,6 +1627,9 @@ msgid "" "as :data:`!copyreg.dispatch_table`. Therefore, one may choose to use a " "modified copy of :data:`!copyreg.dispatch_table` as a private dispatch table." msgstr "" +"由 :mod:`copyreg` 模組管理的全域調度表可以 :data:`!copyreg.dispatch_table` 呼" +"叫。你可以透過這個方式來基於原始 :data:`!copyreg.dispatch_table` 創建一個修改" +"過的版本,作為你的專屬用途的調度表。" #: ../../library/pickle.rst:801 msgid "For example ::" @@ -1212,6 +1652,8 @@ msgid "" "creates an instance of :class:`pickle.Pickler` with a private dispatch table " "which handles the ``SomeClass`` class specially. Alternatively, the code ::" msgstr "" +"建立了一個 :class:`pickle.Pickler`,其中含有專門處裡 ``SomeClass`` 類別的專屬" +"調度表。此外,你也可以寫作:::" #: ../../library/pickle.rst:812 msgid "" @@ -1232,6 +1674,8 @@ msgid "" "does the same but all instances of ``MyPickler`` will by default share the " "private dispatch table. On the other hand, the code ::" msgstr "" +"這樣可產生相似的結果,唯一不同的是往後所有 ``MyPickler`` 預設都會使用這個專屬" +"調度表。最後,如果將程式寫為:::" #: ../../library/pickle.rst:821 msgid "" @@ -1247,11 +1691,11 @@ msgstr "" msgid "" "modifies the global dispatch table shared by all users of the :mod:`copyreg` " "module." -msgstr "" +msgstr "則會改變 :mod:`copyreg` 模組內建、所有使用者共通的調度表。" #: ../../library/pickle.rst:830 msgid "Handling Stateful Objects" -msgstr "" +msgstr "處裡紀錄大量狀態的物件" #: ../../library/pickle.rst:836 msgid "" @@ -1264,6 +1708,12 @@ msgid "" "__setstate__` and :meth:`!__getstate__` methods are used to implement this " "behavior. ::" msgstr "" +"以下的範例展示了如何修改針對特定類別封裝時的行為。下面的 :class:`!" +"TextReader` 類別會開啟一個文字檔案,並在每次呼叫其 :meth:`!readline` 方法時返" +"回當前行編號與該行內容。如果 :class:`!TextReader` 實例被封裝,所有*除了檔案物" +"件之外*的屬性成員都會被保存。在該實例被拆封時,檔案將被重新開啟,並從上次的位" +"置繼續讀取。這個行為的達成是透過 :meth:`!__setstate__` 和 :meth:`!" +"__getstate__` 方法來實作的。::" #: ../../library/pickle.rst:844 msgid "" @@ -1304,10 +1754,45 @@ msgid "" " # Finally, save the file.\n" " self.file = file" msgstr "" +"class TextReader:\n" +" \"\"\"列出文字檔案中的行並對其進行編號。\"\"\"\n" +"\n" +" def __init__(self, filename):\n" +" self.filename = filename\n" +" self.file = open(filename)\n" +" self.lineno = 0\n" +"\n" +" def readline(self):\n" +" self.lineno += 1\n" +" line = self.file.readline()\n" +" if not line:\n" +" return None\n" +" if line.endswith('\\n'):\n" +" line = line[:-1]\n" +" return \"%i: %s\" % (self.lineno, line)\n" +"\n" +" def __getstate__(self):\n" +" # 從 self.__dict__ 中複製物件的狀態。包含了所有的實例屬性。\n" +" # 使用 dict.copy() 方法以避免修改原始狀態。\n" +" state = self.__dict__.copy()\n" +" # 移除不可封裝的項目。\n" +" del state['file']\n" +" return state\n" +"\n" +" def __setstate__(self, state):\n" +" # 恢復實例屬性(即 filename 和 lineno)。\n" +" self.__dict__.update(state)\n" +" # 恢復到先前開啟了檔案的狀態。為此,我們需要重新開啟它並一直讀取到行" +"數編號相同。\n" +" file = open(self.filename)\n" +" for _ in range(self.lineno):\n" +" file.readline()\n" +" # 存檔。\n" +" self.file = file" #: ../../library/pickle.rst:882 msgid "A sample usage might be something like this::" -msgstr "" +msgstr "可以這樣實際使用:::" #: ../../library/pickle.rst:884 msgid "" @@ -1331,7 +1816,7 @@ msgstr "" #: ../../library/pickle.rst:896 msgid "Custom Reduction for Types, Functions, and Other Objects" -msgstr "" +msgstr "針對型別、函數或特定物件定製縮減函數" #: ../../library/pickle.rst:900 msgid "" @@ -1340,6 +1825,9 @@ msgid "" "the object's type, or we may want to customize the pickling of functions and " "classes." msgstr "" +"有時候,:attr:`~Pickler.dispatch_table` 的彈性空間可能不夠。尤其當我們想要使" +"用型別以外的方式來判斷如何使用自訂封裝、或者我們想要自訂特定函式和類別的封裝" +"方法時。" #: ../../library/pickle.rst:905 msgid "" @@ -1349,6 +1837,9 @@ msgid "" "alternatively return :data:`NotImplemented` to fallback to the traditional " "behavior." msgstr "" +"如果是這樣的話,可以繼承 :class:`Pickler` 類別並實作一個 :meth:`~Pickler." +"reducer_override` 方法。此方法可以回傳任意的縮減元組(參閱 :meth:`~object." +"__reduce__`)、也可以回傳 :data:`NotImplemented` 以回退至原始的行為。" #: ../../library/pickle.rst:910 msgid "" @@ -1356,6 +1847,8 @@ msgid "" "reducer_override` are defined, then :meth:`~Pickler.reducer_override` method " "takes priority." msgstr "" +"如果 :attr:`~Pickler.dispatch_table` 和 :meth:`~Pickler.reducer_override` 都" +"被定義了的話,:meth:`~Pickler.reducer_override` 的優先度較高。" #: ../../library/pickle.rst:915 msgid "" @@ -1365,12 +1858,16 @@ msgid "" "class:`dict`, :class:`set`, :class:`frozenset`, :class:`list` and :class:" "`tuple`." msgstr "" +"出於效能考量,處裡以下物件可能不會呼叫 :meth:`~Pickler.reducer_override`:" +"``None``、``True``、``False``,以及 :class:`int`、:class:`float`、:class:" +"`bytes`、:class:`str`、:class:`dict`、:class:`set`、:class:`frozenset`、:" +"class:`list` 和 :class:`tuple` 的實例。" #: ../../library/pickle.rst:921 msgid "" "Here is a simple example where we allow pickling and reconstructing a given " "class::" -msgstr "" +msgstr "以下是一個簡單的例子,我們示範如何允許封裝和重建給定的類別:::" #: ../../library/pickle.rst:924 msgid "" @@ -1402,10 +1899,37 @@ msgid "" "assert unpickled_class.__name__ == \"MyClass\"\n" "assert unpickled_class.my_attribute == 1" msgstr "" +"import io\n" +"import pickle\n" +"\n" +"class MyClass:\n" +" my_attribute = 1\n" +"\n" +"class MyPickler(pickle.Pickler):\n" +" def reducer_override(self, obj):\n" +" \"\"\"MyClass 的自訂縮減函數。\"\"\"\n" +" if getattr(obj, \"__name__\", None) == \"MyClass\":\n" +" return type, (obj.__name__, obj.__bases__,\n" +" {'my_attribute': obj.my_attribute})\n" +" else:\n" +" # 遭遇其他物件,則使用一般的縮減方式\n" +" return NotImplemented\n" +"\n" +"f = io.BytesIO()\n" +"p = MyPickler(f)\n" +"p.dump(MyClass)\n" +"\n" +"del MyClass\n" +"\n" +"unpickled_class = pickle.loads(f.getvalue())\n" +"\n" +"assert isinstance(unpickled_class, type)\n" +"assert unpickled_class.__name__ == \"MyClass\"\n" +"assert unpickled_class.my_attribute == 1\n" #: ../../library/pickle.rst:956 msgid "Out-of-band Buffers" -msgstr "" +msgstr "帶外(Out-of-band)資料緩衝區" #: ../../library/pickle.rst:960 msgid "" @@ -1416,6 +1940,10 @@ msgid "" "structure of objects into a sequential stream of bytes, intrinsically " "involves copying data to and from the pickle stream." msgstr "" +":mod:`pickle` 模組會被用於用於傳輸龐大的資料。此時,將複製記憶體的次數降到最" +"低以保持效能變得很重要。然而,:mod:`pickle` 模組的正常操作過程中,當它將物件" +"的圖狀結構(graph-like structure)轉換為連續的位元組串流時,本質上就涉及將資" +"料複製到封裝流以及從封裝流複製資料。" #: ../../library/pickle.rst:967 msgid "" @@ -1424,10 +1952,12 @@ msgid "" "implementation of the communications system) support the out-of-band " "transfer facilities provided by pickle protocol 5 and higher." msgstr "" +"如果*供給者*(被傳遞物件的型別的實作)與*消費者*(資訊交換系統的實作)都支援" +"由 pickle 協定 5 或更高版本提供的帶外傳輸功能,則可以避免此一先天限制。" #: ../../library/pickle.rst:973 msgid "Provider API" -msgstr "" +msgstr "供給者 API" #: ../../library/pickle.rst:975 msgid "" @@ -1436,6 +1966,9 @@ msgid "" "a :class:`PickleBuffer` instance (instead of e.g. a :class:`bytes` object) " "for any large data." msgstr "" +"要封裝的大型資料物件,則必須實作一個針對 5 版協定及以上的 :meth:`~object." +"__reduce_ex__` 方法,該方法應返回一個 :class:`PickleBuffer` 實例來處理任何大" +"型資料(而非返回如 :class:`bytes` 物件)。" #: ../../library/pickle.rst:980 msgid "" @@ -1445,16 +1978,21 @@ msgid "" "opt-in to tell :mod:`pickle` that they will handle those buffers by " "themselves." msgstr "" +"一個 :class:`PickleBuffer` 物件*指示*了當下底層的緩衝區狀態適合進行帶外資料傳" +"輸。這些物件仍然相容 :mod:`pickle` 模組的一般使用方式。消費者程式也可以選擇介" +"入,指示 :mod:`pickle` 他們將自行處理這些緩衝區。" #: ../../library/pickle.rst:987 msgid "Consumer API" -msgstr "" +msgstr "消費者 API" #: ../../library/pickle.rst:989 msgid "" "A communications system can enable custom handling of the :class:" "`PickleBuffer` objects generated when serializing an object graph." msgstr "" +"一個資訊交換系統可以決定要自行處裡序列化物件圖時產生的 :class:`PickleBuffer` " +"物件。" #: ../../library/pickle.rst:992 msgid "" @@ -1464,6 +2002,10 @@ msgid "" "graph. Buffers accumulated by the *buffer_callback* will not see their data " "copied into the pickle stream, only a cheap marker will be inserted." msgstr "" +"傳送端需要傳遞一個調用緩衝區的回呼函數給 :class:`Pickler`\\ (或 :func:" +"`dump` 或 :func:`dumps` 函數)的 *buffer_callback* 引數,使每次生成 :class:" +"`PickleBuffer` 時,該物件在處理物件圖時能被呼叫。除了一個簡易標記以外,由 " +"*buffer_callback* 累積的緩衝區資料不會被複製到 pickle 串流中。" #: ../../library/pickle.rst:999 msgid "" @@ -1475,6 +2017,12 @@ msgid "" "reconstructors of the objects whose pickling produced the original :class:" "`PickleBuffer` objects." msgstr "" +"接收端需要傳遞一個緩衝區物件給 :class:`Unpickler`\\ (或 :func:`load` 或 :" +"func:`loads` 函式)的 *buffers* 引數。該物件須是一個可疊代的(iterable)緩衝" +"區(buffer)物件,其中包含傳遞給 *buffer_callback* 的緩衝區物件。這個可疊代物" +"件的緩衝區順序應該與它們當初被封裝時傳遞給 *buffer_callback* 的順序相同。這些" +"緩衝區將提供物件重建所需的資料,以使重建器能還原出那個當時產生了 :class:" +"`PickleBuffer` 的物件。" #: ../../library/pickle.rst:1007 msgid "" @@ -1483,6 +2031,8 @@ msgid "" "Potential optimizations include the use of shared memory or datatype-" "dependent compression." msgstr "" +"在傳送與接收端之間,通訊系統可以自由實作轉移帶外緩衝區資料的機制。該機制可能" +"可以利用共用記憶體機制或根據資料類型特定的壓縮方式來最佳化執行速度。" #: ../../library/pickle.rst:1013 msgid "Example" @@ -1493,6 +2043,8 @@ msgid "" "Here is a trivial example where we implement a :class:`bytearray` subclass " "able to participate in out-of-band buffer pickling::" msgstr "" +"這一個簡單的範例展示了如何實作一個可以參與帶外緩衝區封裝的 :class:" +"`bytearray` 子類別:::" #: ../../library/pickle.rst:1018 msgid "" @@ -1517,6 +2069,25 @@ msgid "" " else:\n" " return cls(obj)" msgstr "" +"class ZeroCopyByteArray(bytearray):\n" +"\n" +" def __reduce_ex__(self, protocol):\n" +" if protocol >= 5:\n" +" return type(self)._reconstruct, (PickleBuffer(self),), None\n" +" else:\n" +" # PickleBuffer 在 pickle 協定 <= 4 時禁止使用。\n" +" return type(self)._reconstruct, (bytearray(self),)\n" +"\n" +" @classmethod\n" +" def _reconstruct(cls, obj):\n" +" with memoryview(obj) as m:\n" +" # 取得對原始緩衝區物件的控制\n" +" obj = m.obj\n" +" if type(obj) is cls:\n" +" # 若原本的緩衝區物件是 ZeroCopyByteArray,則直接回傳。\n" +" return obj\n" +" else:\n" +" return cls(obj)" #: ../../library/pickle.rst:1039 msgid "" @@ -1524,12 +2095,16 @@ msgid "" "providing object if it has the right type. This is an easy way to simulate " "zero-copy behaviour on this toy example." msgstr "" +"如果型別正確,重建器(``_reconstruct`` 類別方法)會返回當時提供緩衝區的物件。" +"這個簡易實作可以模擬一個無複製行為的重建器。" #: ../../library/pickle.rst:1043 msgid "" "On the consumer side, we can pickle those objects the usual way, which when " "unserialized will give us a copy of the original object::" msgstr "" +"在使用端,我們可以用一般的方式封裝這些物件,當我們拆封時會得到一個原始物件的" +"副本:::" #: ../../library/pickle.rst:1046 msgid "" @@ -1539,12 +2114,19 @@ msgid "" "print(b == new_b) # True\n" "print(b is new_b) # False: a copy was made" msgstr "" +"b = ZeroCopyByteArray(b\"abc\")\n" +"data = pickle.dumps(b, protocol=5)\n" +"new_b = pickle.loads(data)\n" +"print(b == new_b) # True\n" +"print(b is new_b) # False: 曾進行過複製運算" #: ../../library/pickle.rst:1052 msgid "" "But if we pass a *buffer_callback* and then give back the accumulated " "buffers when unserializing, we are able to get back the original object::" msgstr "" +"但如果我們傳一個 *buffer_callback* 並在去序列化時正確返回積累的緩衝資料,我們" +"就能拿回原始的物件:::" #: ../../library/pickle.rst:1055 msgid "" @@ -1555,6 +2137,12 @@ msgid "" "print(b == new_b) # True\n" "print(b is new_b) # True: no copy was made" msgstr "" +"b = ZeroCopyByteArray(b\"abc\")\n" +"buffers = []\n" +"data = pickle.dumps(b, protocol=5, buffer_callback=buffers.append)\n" +"new_b = pickle.loads(data, buffers=buffers)\n" +"print(b == new_b) # True\n" +"print(b is new_b) # True: 沒有進行過複製" #: ../../library/pickle.rst:1062 msgid "" @@ -1565,14 +2153,18 @@ msgid "" "making as few copies as possible) when transferring between distinct " "processes or systems." msgstr "" +"此範例是因為受限於 :class:`bytearray` 會自行分配記憶體:您無法創建以其他物件" +"的記憶體為基礎的 :class:`bytearray` 實例。不過第三方資料型態(如 NumPy 陣列)" +"則可能沒有這個限制,而允許在不同程序或系統之間傳輸資料時使用零拷貝封裝(或儘" +"可能地減少拷貝次數)。" #: ../../library/pickle.rst:1069 msgid ":pep:`574` -- Pickle protocol 5 with out-of-band data" -msgstr "" +msgstr ":pep:`574` -- 第 5 版 Pickle 協定的帶外資料(out-of-band data)處裡" #: ../../library/pickle.rst:1075 msgid "Restricting Globals" -msgstr "" +msgstr "限制全域物件" #: ../../library/pickle.rst:1080 msgid "" @@ -1581,6 +2173,9 @@ msgid "" "it permits the unpickler to import and invoke arbitrary code. Just consider " "what this hand-crafted pickle data stream does when loaded::" msgstr "" +"預設情況下,拆封過程將會引入任何在 pickle 資料中找到的類別或函式。對於許多應" +"用程式來說,這種行為是不可接受的,因為它讓拆封器能夠引入並執行任意程式碼。請" +"參見以下 pickle 資料流在載入時的行為:::" #: ../../library/pickle.rst:1085 msgid "" @@ -1601,6 +2196,9 @@ msgid "" "is inoffensive, it is not difficult to imagine one that could damage your " "system." msgstr "" +"在這個例子中,拆封器會引入 :func:`os.system` 函式,然後執行命令「echo hello " +"world」。雖然這個例子是無害的,但不難想像可以這個方式輕易執行任意可能對系統造" +"成損害的命令。" #: ../../library/pickle.rst:1094 msgid "" @@ -1610,12 +2208,18 @@ msgid "" "requested. Thus it is possible to either completely forbid globals or " "restrict them to a safe subset." msgstr "" +"基於以上原因,您可能會希望透過自訂 :meth:`Unpickler.find_class` 來控制哪些是" +"能夠被拆封的內容。與其名稱字面意義暗示的不同,實際上每當你請求一個全域物件" +"(例如,類別或函式)時,就會調用 :meth:`Unpickler.find_class`。因此,可以透過" +"這個方法完全禁止全域物件或將其限制在安全的子集合。" #: ../../library/pickle.rst:1100 msgid "" "Here is an example of an unpickler allowing only few safe classes from the :" "mod:`builtins` module to be loaded::" msgstr "" +"以下是一個僅允許從 :mod:`builtins` 模組中載入少數安全類別的拆封器" +"(unpickler)的例子:::" #: ../../library/pickle.rst:1103 msgid "" @@ -1645,10 +2249,35 @@ msgid "" " \"\"\"Helper function analogous to pickle.loads().\"\"\"\n" " return RestrictedUnpickler(io.BytesIO(s)).load()" msgstr "" +"import builtins\n" +"import io\n" +"import pickle\n" +"\n" +"safe_builtins = {\n" +" 'range',\n" +" 'complex',\n" +" 'set',\n" +" 'frozenset',\n" +" 'slice',\n" +"}\n" +"\n" +"class RestrictedUnpickler(pickle.Unpickler):\n" +"\n" +" def find_class(self, module, name):\n" +" # 只允許幾個內建的安全類別\n" +" if module == \"builtins\" and name in safe_builtins:\n" +" return getattr(builtins, name)\n" +" # 完全禁止任何其他類別\n" +" raise pickle.UnpicklingError(\"global '%s.%s' is forbidden\" %\n" +" (module, name))\n" +"\n" +"def restricted_loads(s):\n" +" \"\"\"一個模擬 pickle.loads() 的輔助函數\"\"\"\n" +" return RestrictedUnpickler(io.BytesIO(s)).load()" #: ../../library/pickle.rst:1129 msgid "A sample usage of our unpickler working as intended::" -msgstr "" +msgstr "我們剛才實作的的拆封器範例正常運作的樣子:::" #: ../../library/pickle.rst:1131 msgid "" @@ -1685,10 +2314,13 @@ msgid "" "alternatives such as the marshalling API in :mod:`xmlrpc.client` or third-" "party solutions." msgstr "" +"正如我們的範例所示,必須謹慎審視能被拆封的內容。因此,如果您的應用場景非常關" +"心安全性,您可能需要考慮其他選擇,例如 :mod:`xmlrpc.client` 中的 marshalling " +"API 或其他第三方解決方案。" #: ../../library/pickle.rst:1155 msgid "Performance" -msgstr "" +msgstr "效能" #: ../../library/pickle.rst:1157 msgid "" @@ -1696,6 +2328,9 @@ msgid "" "efficient binary encodings for several common features and built-in types. " "Also, the :mod:`pickle` module has a transparent optimizer written in C." msgstr "" +"較近期的 pickle 協定版本(從 2 版協定開始)為多種常見功能和內建型別提供了高效" +"率的二進位編碼。此外,:mod:`pickle` 模組還具備一個透明化的、以 C 語言編寫的最" +"佳化工具。" #: ../../library/pickle.rst:1165 msgid "Examples" @@ -1704,7 +2339,7 @@ msgstr "範例" #: ../../library/pickle.rst:1167 msgid "" "For the simplest code, use the :func:`dump` and :func:`load` functions. ::" -msgstr "" +msgstr "最簡單的使用方式,調用 :func:`dump` 和 :func:`load` 函式。::" #: ../../library/pickle.rst:1169 msgid "" @@ -1721,10 +2356,22 @@ msgid "" " # Pickle the 'data' dictionary using the highest protocol available.\n" " pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)" msgstr "" +"import pickle\n" +"\n" +"# 任意 pickle 支援的物件。\n" +"data = {\n" +" 'a': [1, 2.0, 3+4j],\n" +" 'b': (\"string\", b\"byte string\"),\n" +" 'c': {None, True, False}\n" +"}\n" +"\n" +"with open('data.pickle', 'wb') as f:\n" +" # 使用可用的最高協定來封裝 'data' 字典。\n" +" pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)\n" #: ../../library/pickle.rst:1183 msgid "The following example reads the resulting pickled data. ::" -msgstr "" +msgstr "以下範例可以讀取前述程式所封裝的 pickle 資料。::" #: ../../library/pickle.rst:1185 msgid "" @@ -1735,6 +2382,11 @@ msgid "" " # have to specify it.\n" " data = pickle.load(f)" msgstr "" +"import pickle\n" +"\n" +"with open('data.pickle', 'rb') as f:\n" +" # 會自動檢測資料使用的協定版本,因此我們不需要手動指定。\n" +" data = pickle.load(f)" #: ../../library/pickle.rst:1199 msgid "Module :mod:`copyreg`" @@ -1742,7 +2394,7 @@ msgstr ":mod:`copyreg` 模組" #: ../../library/pickle.rst:1200 msgid "Pickle interface constructor registration for extension types." -msgstr "" +msgstr "註冊擴充型別的 Pickle 介面建構子。" #: ../../library/pickle.rst:1202 msgid "Module :mod:`pickletools`" @@ -1750,7 +2402,7 @@ msgstr ":mod:`pickletools` 模組" #: ../../library/pickle.rst:1203 msgid "Tools for working with and analyzing pickled data." -msgstr "" +msgstr "用於分析或處裡被封裝資料的工具。" #: ../../library/pickle.rst:1205 msgid "Module :mod:`shelve`" @@ -1758,7 +2410,7 @@ msgstr ":mod:`shelve` 模組" #: ../../library/pickle.rst:1206 msgid "Indexed databases of objects; uses :mod:`pickle`." -msgstr "" +msgstr "索引式資料庫;使用 :mod:`pickle` 實作。" #: ../../library/pickle.rst:1208 msgid "Module :mod:`copy`" @@ -1766,7 +2418,7 @@ msgstr ":mod:`copy` 模組" #: ../../library/pickle.rst:1209 msgid "Shallow and deep object copying." -msgstr "" +msgstr "物件的淺層或深度拷貝。" #: ../../library/pickle.rst:1211 msgid "Module :mod:`marshal`" @@ -1774,7 +2426,7 @@ msgstr ":mod:`marshal` 模組" #: ../../library/pickle.rst:1212 msgid "High-performance serialization of built-in types." -msgstr "" +msgstr "內建型別的高效能序列化。" #: ../../library/pickle.rst:1216 msgid "Footnotes" @@ -1782,25 +2434,29 @@ msgstr "註解" #: ../../library/pickle.rst:1217 msgid "Don't confuse this with the :mod:`marshal` module" -msgstr "" +msgstr "不要將此模組與 :mod:`marshal` 模組混淆" #: ../../library/pickle.rst:1219 msgid "" "This is why :keyword:`lambda` functions cannot be pickled: all :keyword:`!" "lambda` functions share the same name: ````." msgstr "" +"這就是為什麼 :keyword:`lambda` 函式無法被封裝:所有 :keyword:`!lambda` 函式共" +"享相同的名稱:````。" #: ../../library/pickle.rst:1222 msgid "" "The exception raised will likely be an :exc:`ImportError` or an :exc:" "`AttributeError` but it could be something else." msgstr "" +"拋出的例外應該是 :exc:`ImportError` 或 :exc:`AttributeError`,但也可能是其他" +"例外。" #: ../../library/pickle.rst:1225 msgid "" "The :mod:`copy` module uses this protocol for shallow and deep copying " "operations." -msgstr "" +msgstr ":mod:`copy` 模組使用此協定進行淺層及深層複製操作。" #: ../../library/pickle.rst:1228 msgid "" @@ -1809,6 +2465,9 @@ msgid "" "kind of newline characters occurs in persistent IDs, the resulting pickled " "data will become unreadable." msgstr "" +"協定 0 中限制僅能使用英文字母或數字字元來分配持久化 ID 是因為持久化 ID 是由換" +"行符號所分隔的。因此,如果持久化 ID 中出現任何形式的換行字元,將導致封裝資料" +"變得無法讀取。" #: ../../library/pickle.rst:12 msgid "persistence" @@ -1840,7 +2499,7 @@ msgstr "pickling" #: ../../library/pickle.rst:123 msgid "External Data Representation" -msgstr "External Data Representation(外部資料表示法)" +msgstr "External Data Representation(外部資料表現)" #: ../../library/pickle.rst:672 msgid "copy"