Browse Source

🌐 Update translations for zh-hant (update-outdated)

pull/15896/head
github-actions[bot] 3 weeks ago
parent
commit
06d0e9b8b8
  1. 36
      docs/zh-hant/docs/_llm-test.md
  2. 4
      docs/zh-hant/docs/alternatives.md
  3. 160
      docs/zh-hant/docs/async.md
  4. 96
      docs/zh-hant/docs/features.md
  5. 6
      docs/zh-hant/docs/index.md
  6. 38
      docs/zh-hant/docs/python-types.md
  7. 10
      docs/zh-hant/docs/virtual-environments.md

36
docs/zh-hant/docs/_llm-test.md

@ -35,7 +35,7 @@
//// tab | 測試
Yesterday, my friend wrote: "If you spell incorrectly correctly, you have spelled it incorrectly". To which I answered: "Correct, but 'incorrectly' is incorrectly not '"incorrectly"'".
昨天,我的朋友寫道:「如果你正確地拼寫 incorrectly,你就把它拼成 incorrectly 了」。我回答:「正確,但 'incorrectly' 錯在它不是 '"incorrectly"'"」。
/// note | 注意
@ -59,7 +59,7 @@ LLM 很可能會把這段翻譯錯。重點只在於重新翻譯時是否能保
`pip install "foo[bar]"`
程式碼片段中字串常值的例子:"this"、'that'。
程式碼片段中字串常值的例子:`"this"``'that'`
較難的程式碼片段中字串常值例子:`f"I like {'oranges' if orange else "apples"}"`
@ -125,23 +125,23 @@ works(foo="bar") # 這可以運作 🎉
//// tab | 測試
/// note | 注意
Some text
一些文字
///
/// note | 技術細節
Some text
一些文字
///
/// tip | 提示
Some text
一些文字
///
/// warning | 警告
Some text
一些文字
///
/// danger | 危險
Some text
一些文字
///
////
@ -222,15 +222,15 @@ Some text
### 開發網頁應用程式 - 教學 { #develop-a-webapp-a-tutorial }
Hello.
你好。
### 型別提示與註解 { #type-hints-and-annotations }
Hello again.
再次你好。
### 超類與子類別 { #super-and-subclasses }
Hello again.
再次你好。
////
@ -248,15 +248,15 @@ Hello again.
//// tab | 測試
* you
* your
*
* 你的
* e.g.
* etc.
* 例如
* 等等
* `foo` as an `int`
* `bar` as a `str`
* `baz` as a `list`
* `foo` 作為 `int`
* `bar` 作為 `str`
* `baz` 作為 `list`
* 教學 - 使用者指南
* 進階使用者指南
@ -283,7 +283,7 @@ Hello again.
* 即時
* 標準
* 預設
* 分大小寫
* 分大小寫
* 不區分大小寫
* 提供應用程式服務

4
docs/zh-hant/docs/alternatives.md

@ -80,7 +80,7 @@ Requests 設計非常簡單直觀、容易使用,且有合理的預設值。
因此,如其官網所言:
> Requests is one of the most downloaded Python packages of all time
> Requests 是有史以來下載次數最多的 Python 套件之一
用法非常簡單。例如,發出一個 `GET` 請求,你會寫:
@ -213,7 +213,7 @@ APISpec 由與 Marshmallow 相同的開發者創建。
它是個很棒但被低估的工具。它理應比許多 Flask 外掛更受歡迎,可能因為它的文件過於簡潔與抽象。
這解決了在 Python 文件字串中撰寫 YAML(另一種語法)的问题
這解決了在 Python 文件字串中撰寫 YAML(另一種語法)的問題
在打造 **FastAPI** 前,我最喜歡的後端技術組合就是 Flask、Flask-apispec、Marshmallow 與 Webargs。

160
docs/zh-hant/docs/async.md

@ -2,7 +2,7 @@
有關*路徑操作函式*的 `async def` 語法的細節與非同步 (asynchronous) 程式碼、並行 (concurrency) 與平行 (parallelism) 的一些背景知識。
## 趕時間嗎? { #in-a-hurry }
## 趕時間嗎 { #in-a-hurry }
<abbr title="too long; didn't read - 太長不看"><strong>TL;DR:</strong></abbr>
@ -14,7 +14,6 @@ results = await some_library()
然後,使用 `async def` 宣告你的*路徑操作函式*:
```Python hl_lines="2"
@app.get('/')
async def read_results():
@ -49,7 +48,7 @@ def results():
---
**注意**:你可以在*路徑操作函式*中混合使用 `def``async def` ,並使用最適合你需求的方式來定義每個函式。FastAPI 會幫你做正確的處理。
**注意**:你可以在*路徑操作函式*中混合使用 `def``async def`,並使用最適合你需求的方式來定義每個函式。FastAPI 會幫你做正確的處理。
無論如何,在上述哪種情況下,FastAPI 仍將以非同步方式運行,並且速度非常快。
@ -57,7 +56,7 @@ def results():
## 技術細節 { #technical-details }
現代版本的 Python 支援使用 **「協程」** 的 **`async``await`** 語法來寫 **「非同步程式碼」**。
現代版本的 Python 支援使用稱為 **「協程」** 的東西,透過 **`async``await`** 語法來寫 **「非同步程式碼」**。
接下來我們逐一介紹:
@ -67,39 +66,40 @@ def results():
## 非同步程式碼 { #asynchronous-code }
非同步程式碼僅意味著程式語言 💬 有辦法告訴電腦/程式 🤖 在程式碼中的某個點,它 🤖 需要等待某些事情完成。讓我們假設這些事情被稱為「慢速檔案」📝。
非同步程式碼僅意味著程式語言 💬 有辦法告訴電腦 / 程式 🤖 在程式碼中的某個點,它 🤖 需要等待其他地方的*某些事情*完成。讓我們假設這個*某些事情*被稱為「慢速檔案」📝。
因此,在「慢速檔案」📝 完成的這段時間,電腦可以去處理一些其他工作。
因此,在等待「慢速檔案」📝 完成的這段時間,電腦可以去處理一些其他工作。
接著電腦 / 程式 🤖 會在每次有機會時回來,因為它又在等待,或是在它 🤖 完成當時手上的所有工作時回來。然後它 🤖 會查看是否有任何等待中的任務已經完成,並執行必要的後續操作。
著程式 🤖 會在有空檔時回來查看是否有等待的工作已經完成,並執行必要的後續操作。
下來,它 🤖 取得第一個完成的任務(例如我們的「慢速檔案」📝),並繼續執行與之相關的所有操作。
接下來,它 🤖 完成第一個工作(例如我們的「慢速檔案」📝)並繼續執行相關的所有操作。
這個「等待其他事情」通常指的是一些相對較慢的(與處理器和 RAM 記憶體的速度相比)的 <abbr title="Input and Output - 輸入與輸出">I/O</abbr> 操作,比如說:
這個「等待其他事情」通常指的是一些相對較慢的(與處理器和 RAM 記憶體的速度相比)的 <abbr title="Input and Output - 輸入與輸出">I/O</abbr> 操作,比如說等待:
* 透過網路傳送來自用戶端的資料
* 從網路接收來自用戶端的資料
* 從磁碟讀取檔案內容
* 將內容寫入磁碟
* 你的程式傳送的資料透過網路被用戶端接收
* 系統從磁碟讀取檔案內容並提供給你的程式
* 你的程式交給系統的內容被寫入磁碟
* 遠端 API 操作
* 資料庫操作
* 資料庫查詢
* 資料庫操作完成
* 資料庫查詢回傳結果
* 等等
由於大部分的執行時間都消耗在等待 <abbr title="Input and Output - 輸入與輸出">I/O</abbr> 操作上,因此這些操作被稱為 "I/O 密集型" 操作。
由於大部分的執行時間都消耗在等待 <abbr title="Input and Output - 輸入與輸出">I/O</abbr> 操作上,因此這些操作被稱為 "I/O bound" 操作。
之所以稱為「非同步」,是因為電腦/程式不需要與那些耗時的任務「同步」,等待任務完成的精確時間,然後才能取得結果並繼續工作。
之所以稱為「非同步」,是因為電腦 / 程式不需要與那些耗時的任務「同步」,在什麼都不做的情況下等待任務完成的精確時間,才能取得任務結果並繼續工作。
相反地,非同步系統在任務完成後,可以讓任務稍微等一下(幾微秒),等待電腦/程式完成手頭上的其他工作,然後再回來取得結果繼續進行。
相反地,作為一個「非同步」系統,任務完成後,可以讓任務稍微排隊等一下(幾微秒),等待電腦 / 程式完成手頭上的其他工作,然後再回來取得結果繼續進行。
相對於「非同步」(asynchronous),「同步」(synchronous)也常被稱作「順序性」(sequential),因為電腦/程式會依序執行所有步驟,即便這些步驟涉及等待,才會切換到其他任務。
相對於「非同步」(asynchronous),「同步」(synchronous)也常被稱作「順序性」(sequential),因為電腦 / 程式會依序執行所有步驟,即便這些步驟涉及等待,才會切換到其他任務。
### 並行與漢堡 { #concurrency-and-burgers }
上述非同步程式碼的概念有時也被稱為「並行」,它不同於「平行」。
上述**非同步**程式碼的概念有時也被稱為**「並行」**,它不同於**「平行」**
並行和平行都與 "不同的事情或多或少同時發生" 有關。
**並行**和平行都與 "不同的事情或多或少同時發生" 有關。
但並行和平行之間的細節是完全不同的。
*並行*和平行之間的細節是完全不同的。
為了理解差異,請想像以下有關漢堡的故事:
@ -113,7 +113,7 @@ def results():
<img src="/img/async/concurrent-burgers/concurrent-burgers-02.png" class="illustration">
收銀員通知廚房準備你的漢堡(儘管他們還在為前面其他顧客準備食物)。
收銀員通知廚房的廚師,讓他們知道需要準備你的漢堡(儘管他們還在為前面其他顧客準備食物)。
<img src="/img/async/concurrent-burgers/concurrent-burgers-03.png" class="illustration">
@ -125,7 +125,7 @@ def results():
在等待漢堡的同時,你可以與戀人選一張桌子,然後坐下來聊很長一段時間(因為漢堡十分豪華,準備特別費工。)
這段時間,你還能欣賞你的戀人有多麼的可愛、聰明與迷人。✨😍✨
當你和戀人坐在桌邊等待漢堡時,你可以把這段時間拿來欣賞你的戀人有多麼棒、可愛又聰明 ✨😍✨。
<img src="/img/async/concurrent-burgers/concurrent-burgers-05.png" class="illustration">
@ -135,7 +135,7 @@ def results():
<img src="/img/async/concurrent-burgers/concurrent-burgers-06.png" class="illustration">
你和戀人享用這頓大餐,整個過程十分開心✨
你和戀人享用這頓大餐,整個過程十分開心
<img src="/img/async/concurrent-burgers/concurrent-burgers-07.png" class="illustration">
@ -147,21 +147,21 @@ def results():
---
想像你是故事中的電腦程式 🤖。
想像你是故事中的電腦 / 程式 🤖。
當你排隊時,你在放空😴,等待輪到你,沒有做任何「生產性」的事情。但這沒關係,因為收銀員只是接單(而不是準備食物),所以排隊速度很快。
然後,當輪到你時,你開始做真正「有生產力」的工作,處理菜單,決定你想要什麼,替戀人選擇餐點,付款,確認你給了正確的帳單或信用卡,檢查你是否被正確收費,確認訂單中的項目是否正確等等。
然後,當輪到你時,你開始做真正「有生產力」的工作,處理菜單,決定你想要什麼,取得戀人的選擇,付款,確認你給了正確的帳單或信用卡,檢查你是否被正確收費,確認訂單中的項目是否正確等等。
但是,即使你還沒有拿到漢堡,你與收銀員的工作已經「暫停」了 ⏸,因為你必須等待 🕙 漢堡準備好。
但當你離開櫃檯,坐到桌子旁,拿著屬於你的號碼等待時,你可以把注意力 🔀 轉移到戀人身上,並開始「工作」⏯ 🤓——也就是和戀人調情 😍。這時你又開始做一些非常「有生產力」的事情。
接著,收銀員 💁 將你的號碼顯示在櫃檯螢幕上,並告訴你「漢堡已經做好了」。但你不會瘋狂地立刻跳起來,因為顯示的號碼變成了你的。你知道沒有人會搶走你的漢堡,因為你有自己的號碼,他們也有他們的號碼。
接著,收銀員 💁 透過把你的號碼顯示在櫃檯螢幕上,表示「漢堡已經做好了」,但你不會在顯示的號碼變成你的號碼時就瘋狂地立刻跳起來。你知道沒有人會搶走你的漢堡,因為你有自己的號碼,他們也有他們的號碼。
所以你會等戀人講完故事(完成當前的工作 ⏯/正在進行的任務 🤓),然後微笑著溫柔地說你要去拿漢堡了 ⏸。
所以你會等戀人講完故事(完成當前的工作 ⏯ / 正在進行的任務 🤓),然後微笑著溫柔地說你要去拿漢堡了 ⏸。
然後你走向櫃檯 🔀,回到已經完成的最初任務 ⏯,拿起漢堡,說聲謝謝,並帶回桌上。這就結束了與櫃檯的互動步驟/任務 ⏹,接下來會產生一個新的任務,「吃漢堡」 🔀 ⏯,而先前的「拿漢堡」任務已經完成了 ⏹。
然後你走向櫃檯 🔀,回到已經完成的最初任務 ⏯,拿起漢堡,說聲謝謝,並帶回桌上。這就結束了與櫃檯互動的步驟 / 任務 ⏹。接著,這又產生了一個新的任務,「吃漢堡」🔀 ⏯,而先前的「拿漢堡」任務已經完成了 ⏹。
### 平行漢堡 { #parallel-burgers }
@ -181,19 +181,19 @@ def results():
<img src="/img/async/parallel-burgers/parallel-burgers-02.png" class="illustration">
收銀員走進廚房準備食物
收銀員走進廚房。
你站在櫃檯前等待 🕙,以免其他人先拿走你的漢堡,因為這裡沒有號碼牌系統。
<img src="/img/async/parallel-burgers/parallel-burgers-03.png" class="illustration">
由於你和戀人都忙著不讓別人搶走你的漢堡,等漢堡準備好時,你根本無法專心和戀人互動。😞
由於你和戀人都忙著不讓別人插到你前面並在漢堡送來時拿走你的漢堡,你根本無法專心和戀人互動。😞
這是「同步」(synchronous)工作,你和收銀員/廚師 👨‍🍳 是「同步化」的。你必須等到 🕙 收銀員/廚師 👨‍🍳 完成漢堡並交給你的那一刻,否則別人可能會拿走你的餐點。
這是「同步」(synchronous)工作,你和收銀員 / 廚師 👨‍🍳 是「同步化」的。你必須等到 🕙 收銀員 / 廚師 👨‍🍳 完成漢堡並交給你的那一刻,否則別人可能會拿走你的餐點。
<img src="/img/async/parallel-burgers/parallel-burgers-04.png" class="illustration">
最終,經過長時間的等待 🕙,收銀員/廚師 👨‍🍳 拿著漢堡回來了。
最終,經過長時間在櫃檯前的等待 🕙,收銀員 / 廚師 👨‍🍳 拿著漢堡回來了。
<img src="/img/async/parallel-burgers/parallel-burgers-05.png" class="illustration">
@ -203,7 +203,7 @@ def results():
<img src="/img/async/parallel-burgers/parallel-burgers-06.png" class="illustration">
整個過程中沒有太多談情說愛,因為大部分時間 🕙 都花在櫃檯前等待。😞
整個過程中沒有太多聊天或談情說愛,因為大部分時間 🕙 都花在櫃檯前等待。😞
/// note | 注意
@ -213,15 +213,15 @@ def results():
---
在這個平行漢堡的情境下,你是一個程式 🤖 且有兩個處理器(你和戀人),兩者都在等待 🕙 並專注於等待櫃檯上的餐點 🕙,等待的時間非常長。
在這個平行漢堡的情境下,你是一個程式 🤖 且有兩個處理器(你和戀人),兩者都在等待 🕙 並專注在櫃檯前等待 🕙,等待的時間非常長。
這家速食店有 8 個處理器(收銀員/廚師)。而並行漢堡店可能只有 2 個處理器(一位收銀員和一位廚師)。
這家速食店有 8 個處理器(收銀員 / 廚師)。而並行漢堡店可能只有 2 個處理器(一位收銀員和一位廚師)。
儘管如此,最終的體驗並不是最理想的。😞
---
這是與漢堡類似的故事。🍔
這是與漢堡類似的平行版本故事。🍔
一個更「現實」的例子,想像一間銀行。
@ -241,29 +241,29 @@ def results():
許多用戶正在使用你的應用程式,而你的伺服器則在等待 🕙 這些用戶不那麼穩定的網路來傳送請求。
接著,再次等待 🕙 回應。
接著,再次等待 🕙 回應回來
這種「等待」 🕙 通常以微秒來衡量,但累加起來,最終還是花費了很多等待時間。
這種「等待」🕙 通常以微秒來衡量,但累加起來,最終還是花費了很多等待時間。
這就是為什麼對於 Web API 來說,使用非同步程式碼 ⏸🔀⏯ 是非常有意的。
這就是為什麼對於 Web API 來說,使用非同步程式碼 ⏸🔀⏯ 是非常有意的。
這種類型的非同步性正是 NodeJS 成功的原因(儘管 NodeJS 不是平行的),這也是 Go 語言作為程式語言的一個強大優勢。
這與 **FastAPI** 所能提供的性能水平相同。
這與 **FastAPI** 所能提供的效能水準相同。
你可以同時利用並行性和平行性,進一步提升效能,這比大多數已測試的 NodeJS 框架都更快,並且與 Go 語言相當,而 Go 是一種更接近 C 的編譯語言([感謝 Starlette](https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1))。
你可以同時利用平行性和非同步性,進一步提升效能,這比大多數已測試的 NodeJS 框架都更快,並且與 Go 語言相當,而 Go 是一種更接近 C 的編譯語言([這都要歸功於 Starlette](https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1))。
### 並行比平行更好嗎 { #is-concurrency-better-than-parallelism }
### 並行比平行更好嗎 { #is-concurrency-better-than-parallelism }
不是的!這不是故事的本意。
並行與平行不同。並行在某些 **特定** 的需要大量等待的情境下表現更好。正因如此,並行在 Web 應用程式開發中通常比平行更有優勢。但並不是所有情境都如此。
因此,為了平衡報導,想像下面這個短故事
因此,為了平衡報導,想像下面這個短故事
> 你需要打掃一間又大又髒的房子。
*是的,這就是全部的故事*
*是的,這就是全部的故事*
---
@ -273,32 +273,32 @@ def results():
無論輪流執行與否(並行),你都需要相同的工時完成任務,同時需要執行相同工作量。
但是,在這種情境下,如果你可以邀請8位前收銀員/廚師(現在是清潔工)來幫忙,每個人(加上你)負責房子的某個區域,這樣你就可以 **平行** 地更快完成工作。
但是,在這種情境下,如果你可以邀請 8 位前收銀員 / 廚師(現在是清潔工)來幫忙,每個人(加上你)負責房子的某個區域,這樣你就可以在額外協助下 **平行** 地更快完成工作。
在這個場景中,每個清潔工(包括你)都是一個處理器,完成工作的一部分。
由於大多數的執行時間都花在實際的工作上(而不是等待),而電腦中的工作由 <abbr title="Central Processing Unit - 中央處理器">CPU</abbr> 完成,因此這些問題被稱為「CPU 密集型」。
由於大多數的執行時間都花在實際的工作上(而不是等待),而電腦中的工作由 <abbr title="Central Processing Unit - 中央處理器">CPU</abbr> 完成,因此這些問題被稱為「CPU bound」。
---
常見的 CPU 密集型操作範例包括那些需要進行複雜數學計算的任務。
常見的 CPU bound 操作範例包括那些需要進行複雜數學計算的任務。
例如:
* **音訊**或**圖像處理**
* **電腦視覺**:一張圖片由數百萬個像素組成,每個像素有 3 個值/顏色,處理這些像素通常需要同時進行大量計算
* **機器學習**: 通常需要大量的「矩陣」和「向量」運算。想像一個包含數字的巨大電子表格,並所有的數字同時相乘;
* **深度學習**: 這是機器學習的子領域,同樣適用。只不過這不僅僅是一張數字表格,而是大量的數據集合,並且在很多情況下,你會使用特殊的處理器來構建或使用這些模型。
* **音訊**或**圖像處理**
* **電腦視覺**:一張圖片由數百萬個像素組成,每個像素有 3 個值 / 顏色,處理這些像素通常需要同時進行大量計算
* **機器學習**通常需要大量的「矩陣」和「向量」運算。想像一個包含數字的巨大電子表格,並將所有數字同時相乘。
* **深度學習**這是機器學習的子領域,同樣適用。只不過這不僅僅是一張要相乘的數字表格,而是大量的數據集合,並且在很多情況下,你會使用特殊的處理器來構建及 / 或使用這些模型。
### 並行 + 平行: Web + 機器學習 { #concurrency-parallelism-web-machine-learning }
使用 **FastAPI**,你可以利用並行的優勢,這在 Web 開發中非常常見(這也是 NodeJS 的最大吸引力)。
但你也可以利用平行與多行程 (multiprocessing)(讓多個行程同時運行) 的優勢來處理機器學習系統中的 **CPU 密集型**工作。
但你也可以利用平行與多行程 (multiprocessing)(讓多個行程同時運行) 的優勢來處理機器學習系統中的 **CPU bound** 工作。
這一點,再加上 Python 是 **資料科學**、機器學習,尤其是深度學習的主要語言,讓 **FastAPI** 成為資料科學/機器學習 Web API 和應用程式(以及許多其他應用程式)的絕佳選擇。
這一點,再加上 Python 是 **資料科學**、機器學習,尤其是深度學習的主要語言,讓 **FastAPI** 成為資料科學 / 機器學習 Web API 和應用程式(以及許多其他應用程式)的絕佳選擇。
想了解如何在生產環境中實現這種平行性,請參見 [](deployment/index.md)。
想了解如何在生產環境中實現這種平行性,請參見 [](deployment/index.md)。
## `async``await` { #async-and-await }
@ -310,37 +310,37 @@ def results():
burgers = await get_burgers(2)
```
這裡的關鍵是 `await`。它告訴 Python 必須等待 ⏸ `get_burgers(2)` 完成它的工作 🕙, 然後將結果儲存在 `burgers` 中。如此,Python 就可以在此期間去處理其他事情 🔀 ⏯ (例如接收另一個請求)。
這裡的關鍵是 `await`。它告訴 Python 必須等待 ⏸ `get_burgers(2)` 完成它的工作 🕙,然後將結果儲存在 `burgers` 中。如此,Python 就可以在此期間去處理其他事情 🔀 ⏯(例如接收另一個請求)。
要讓 `await` 運作,它必須位於支非同步功能的函式內。為此,只需使用 `async def` 宣告函式:
要讓 `await` 運作,它必須位於支非同步功能的函式內。為此,只需使用 `async def` 宣告函式:
```Python hl_lines="1"
async def get_burgers(number: int):
# Do some asynchronous stuff to create the burgers
# 做一些非同步的事情來製作漢堡
return burgers
```
...而不是 `def`:
...而不是 `def`
```Python hl_lines="2"
# This is not asynchronous
# 這不是非同步的
def get_sequential_burgers(number: int):
# Do some sequential stuff to create the burgers
# 做一些循序的事情來製作漢堡
return burgers
```
使用 `async def`,Python 知道在該函式內需要注意 `await`,並且它可以「暫停」 ⏸ 執行該函式,然後執行其他任務 🔀 後回來。
使用 `async def`,Python 知道在該函式內需要注意 `await` 運算式,並且它可以「暫停」⏸ 執行該函式,然後執行其他任務 🔀 後回來。
當你想要呼叫 `async def` 函式時,必須使用「await」。因此,這樣寫將無法運行:
```Python
# This won't work, because get_burgers was defined with: async def
# 這不會運作,因為 get_burgers 是用 async def 定義的
burgers = get_burgers(2)
```
---
如果你正在使用某個函式庫,它告訴你可以使用 `await` 呼叫它,那麼你需要用 `async def` 定義*路徑操作函式*,如:
如果你正在使用某個函式庫,它告訴你可以使用 `await` 呼叫它,那麼你需要用 `async def` 建立使用它的*路徑操作函式*,如:
```Python hl_lines="2-3"
@app.get('/burgers')
@ -357,7 +357,7 @@ async def read_burgers():
那麼,這就像「先有雞還是先有蛋」的問題,要如何呼叫第一個 `async` 函式呢?
如果你使用 FastAPI,無需擔心這個問題,因為「第一個」函式將是你的*路徑操作函式*,FastAPI 會知道如何正確處理這個問題。
如果你使用 **FastAPI**,無需擔心這個問題,因為「第一個」函式將是你的*路徑操作函式*,FastAPI 會知道如何正確處理這個問題。
但如果你想在沒有 FastAPI 的情況下使用 `async` / `await`,你也可以這樣做。
@ -367,9 +367,9 @@ Starlette(和 **FastAPI**)是基於 [AnyIO](https://anyio.readthedocs.io/en/
特別是,你可以直接使用 [AnyIO](https://anyio.readthedocs.io/en/stable/) 來處理更複雜的並行使用案例,這些案例需要你在自己的程式碼中使用更高階的模式。
即使你不使用 **FastAPI**,你也可以使用 [AnyIO](https://anyio.readthedocs.io/en/stable/) 來撰寫自己的非同步應用程式,並獲得高相容性及一些好處(例如「結構化並行」)。
即使你不使用 FastAPI,你也可以使用 [AnyIO](https://anyio.readthedocs.io/en/stable/) 來撰寫自己的非同步應用程式,並獲得高相容性及一些好處(例如*結構化並行*)。
我另外在 AnyIO 之上做了一個薄封裝的函式庫,稍微改進型別註解以獲得更好的**自動補全**、**即時錯誤**等。同時它也提供友善的介紹與教學,幫助你**理解**並撰寫**自己的非同步程式碼**:[Asyncer](https://asyncer.tiangolo.com/)。當你需要**將非同步程式碼與一般**(阻塞/同步)**程式碼整合**時,它特別實用。
我另外在 AnyIO 之上做了一個薄封裝的函式庫,稍微改進型別註解以獲得更好的**自動補全**、**即時錯誤**等。同時它也提供友善的介紹與教學,幫助你**理解**並撰寫**自己的非同步程式碼**:[Asyncer](https://asyncer.tiangolo.com/)。當你需要**將非同步程式碼與一般**(阻塞 / 同步)**程式碼整合**時,它特別實用。
### 其他形式的非同步程式碼 { #other-forms-of-asynchronous-code }
@ -381,21 +381,21 @@ Starlette(和 **FastAPI**)是基於 [AnyIO](https://anyio.readthedocs.io/en/
但在此之前,處理非同步程式碼要更加複雜和困難。
在較舊的 Python 版本中,你可能會使用多執行緒或 [Gevent](https://www.gevent.org/)。但這些程式碼要更難以理解、調試和思考。
在較舊的 Python 版本中,你可能會使用多執行緒或 [Gevent](https://www.gevent.org/)。但這些程式碼要更難以理解、偵錯和思考。
在較舊的 NodeJS / 瀏覽器 JavaScript 中,你會使用「回呼」,這可能會導致“回呼地獄”
在較舊的 NodeJS / 瀏覽器 JavaScript 中,你會使用「回呼」。這可能會導致「回呼地獄」
## 協程 { #coroutines }
「協程」只是 `async def` 函式所回傳的非常特殊的事物名稱。Python 知道它是一個類似函式的東西,可以啟動它,並且在某個時刻它會結束,但它也可能在內部暫停 ⏸,只要遇到 `await`
**協程**只是 `async def` 函式所回傳的非常特殊的事物名稱。Python 知道它是一個類似函式的東西,可以啟動它,並且在某個時刻它會結束,但它也可能在內部暫停 ⏸,只要遇到 `await`
這種使用 `async``await` 的非同步程式碼功能通常被概括為「協程」。這與 Go 語言的主要特性「Goroutines」相似。
這種使用 `async``await` 的非同步程式碼功能通常被概括為使用「協程」。這與 Go 語言的主要特性「Goroutines」相似。
## 結論 { #conclusion }
讓我們再次回顧之前的句子:
> 現代版本的 Python 支持使用 **"協程"** 的 **`async``await`** 語法來寫 **"非同步程式碼"**。
> 現代版本的 Python 支援使用稱為 **「協程」** 的東西,透過 **`async``await`** 語法來寫 **「非同步程式碼」**。
現在應該能明白其含意了。✨
@ -407,7 +407,7 @@ Starlette(和 **FastAPI**)是基於 [AnyIO](https://anyio.readthedocs.io/en/
你大概可以跳過這段。
這裡是有關 FastAPI 內部技術細節。
這裡是有關 **FastAPI** 底層如何運作的非常技術性的細節。
如果你有相當多的技術背景(例如協程、執行緒、阻塞等),並且對 FastAPI 如何處理 `async def` 與常規 `def` 感到好奇,請繼續閱讀。
@ -415,9 +415,9 @@ Starlette(和 **FastAPI**)是基於 [AnyIO](https://anyio.readthedocs.io/en/
### 路徑操作函式 { #path-operation-functions }
當你使用 `def` 而不是 `async def` 宣告*路徑操作函式*時,該函式會在外部的執行緒池(threadpool)中執行,然後等待結果,而不是直接呼叫(因為這樣會阻塞伺服器)。
當你使用一般的 `def` 而不是 `async def` 宣告*路徑操作函式*時,該函式會在外部的執行緒池(threadpool)中執行,然後等待結果,而不是直接呼叫(因為這樣會阻塞伺服器)。
如果你來自於其他不以這種方式運作的非同步框架,而且你習慣於使用普通的 `def` 定義僅進行簡單計算的*路徑操作函式*,目的是獲得微小的能增益(大約 100 奈秒),請注意,在 FastAPI 中,效果會完全相反。在這些情況下,最好使用 `async def`,除非你的*路徑操作函式*執行阻塞的 <abbr title="Input/Output - 輸入/輸出: 磁碟讀寫或網路通訊。">I/O</abbr> 的程式碼。
如果你來自於其他不以這種方式運作的非同步框架,而且你習慣於使用普通的 `def` 定義僅進行簡單計算的*路徑操作函式*,目的是獲得微小的能增益(大約 100 奈秒),請注意,在 **FastAPI** 中,效果會完全相反。在這些情況下,最好使用 `async def`,除非你的*路徑操作函式*執行阻塞的 <abbr title="Input/Output - 輸入/輸出: 磁碟讀取或寫入、網路通訊。">I/O</abbr> 的程式碼。
不過,在這兩種情況下,**FastAPI** [仍然很快](index.md#performance),至少與你之前的框架相當(或者更快)。
@ -427,18 +427,18 @@ Starlette(和 **FastAPI**)是基於 [AnyIO](https://anyio.readthedocs.io/en/
### 子依賴項 { #sub-dependencies }
你可以擁有多個相互依賴的依賴項和[子依賴項](tutorial/dependencies/sub-dependencies.md)(作為函式定義的參數),其中一些可能是用 `async def` 宣告,也可能是用 `def` 宣告。它們仍然可以正常運作,用 `def` 定義的那些將會在外部的執行緒中呼叫(來自執行緒池),而不是被「等待」。
你可以擁有多個相互依賴的依賴項和[子依賴項](tutorial/dependencies/sub-dependencies.md)(作為函式定義的參數),其中一些可能是用 `async def` 宣告,也可能是用一般的 `def` 宣告。它們仍然可以正常運作,用一般的 `def` 定義的那些將會在外部的執行緒中呼叫(來自執行緒池),而不是被「等待」。
### 其他輔助函式 { #other-utility-functions }
你可以直接呼叫任何使用 `def``async def` 建立的其他輔助函式,FastAPI 不會影響你呼叫它們的方式。
你可以直接呼叫任何使用一般的 `def``async def` 建立的其他輔助函式,FastAPI 不會影響你呼叫它們的方式。
這與 FastAPI 為你呼叫*路徑操作函式*和依賴項的邏輯有所不同
這與 FastAPI 為你呼叫的函式有所不同:*路徑操作函式*和依賴項。
如果你的輔助函式是用 `def` 宣告的,它將會被直接呼叫(按照你在程式碼中撰寫的方式),而不是在執行緒池中。如果該函式是用 `async def` 宣告,那麼你在呼叫時應該使用 `await` 等待其結果。
如果你的輔助函式是用 `def` 宣告的一般函式,它將會被直接呼叫(按照你在程式碼中撰寫的方式),而不是在執行緒池中。如果該函式是用 `async def` 宣告,那麼你在程式碼中呼叫時應該使用 `await` 等待其結果。
---
再一次強調,這些都是非常技術性的細節,如果你特地在尋找這些資訊,這些內容可能會對你有幫助。
否則,只需遵循上面提到的指引即可:<a href="#in-a-hurry">趕時間嗎?</a>
否則,只需遵循上面提到章節的指引即可:<a href="#in-a-hurry">趕時間嗎</a>

96
docs/zh-hant/docs/features.md

@ -6,14 +6,14 @@
### 建立在開放標準的基礎上 { #based-on-open-standards }
* 使用 [**OpenAPI**](https://github.com/OAI/OpenAPI-Specification) 來建立 API,包含 <dfn title="也稱為:端點、路由">路徑</dfn><dfn title="也稱為 HTTP 方法,例如 POST、GET、PUT、DELETE">操作</dfn>、參數、請求內文、安全性等宣告。
* 使用 [**OpenAPI**](https://github.com/OAI/OpenAPI-Specification) 來建立 API,包含 <dfn title="也稱為:端點、路由">路徑</dfn> <dfn title="也稱為 HTTP 方法,例如 POST、GET、PUT、DELETE">操作</dfn>、參數、請求內文、安全性等宣告。
* 使用 [**JSON Schema**](https://json-schema.org/)(因為 OpenAPI 本身就是基於 JSON Schema)自動生成資料模型文件。
* 經過縝密的研究後圍繞這些標準進行設計,而不是事後在已有系統上附加的一層功能。
* 這也讓我們在多種語言中可以使用自動**用戶端程式碼生成**。
### 能夠自動生成文件 { #automatic-docs }
FastAPI 能生成互動式 API 文件和探索性的 Web 使用者介面。由於該框架基於 OpenAPI,因此有多種選擇,預設提供了兩種。
互動式 API 文件與探索用的 Web 使用者介面。由於該框架基於 OpenAPI,因此有多種選擇,預設包含 2 種。
* [**Swagger UI**](https://github.com/swagger-api/swagger-ui) 提供互動式探索,讓你可以直接從瀏覽器呼叫並測試你的 API 。
@ -27,22 +27,22 @@ FastAPI 能生成互動式 API 文件和探索性的 Web 使用者介面。由
這一切都基於標準的 **Python 型別**宣告(感謝 Pydantic)。無需學習新的語法,只需使用標準的現代 Python。
如果你需要 2 分鐘來習如何使用 Python 型別(即使你不使用 FastAPI),可以看看這個簡短的教學:[Python 型別](python-types.md)。
如果你需要 2 分鐘來習如何使用 Python 型別(即使你不使用 FastAPI),可以看看這個簡短的教學:[Python 型別](python-types.md)。
如果你寫帶有 Python 型別的程式碼
寫帶有型別的標準 Python:
```Python
from datetime import date
from pydantic import BaseModel
# 宣告一個變數為 string
# 並在函式中獲得 editor support
# 將變數宣告為 str
# 並在函式內取得 editor support
def main(user_id: str):
return user_id
# 宣告一個 Pydantic model
# 一個 Pydantic model
class User(BaseModel):
id: int
name: str
@ -65,9 +65,9 @@ my_second_user: User = User(**second_user_data)
/// note
`**second_user_data` 意思是:
`**second_user_data` 意思是
`second_user_data` 字典直接作為 key-value 引數傳遞,等同於:`User(id=4, name="Mary", joined="2018-11-30")`
`second_user_data` dict 的 keys 和 values 直接作為 key-value 引數傳遞,等同於:`User(id=4, name="Mary", joined="2018-11-30")`
///
@ -75,31 +75,31 @@ my_second_user: User = User(**second_user_data)
整個框架的設計是為了讓使用變得簡單且直觀,在開始開發之前,所有決策都在多個編輯器上進行了測試,以確保提供最佳的開發體驗。
最近的 Python 開發者調查中,我們能看到[被使用最多的功能是 autocompletion](https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features)。
Python 開發者調查中,我們能清楚看到[最常用的功能之一是「autocompletion」](https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features)。
整個 **FastAPI** 框架就是基於這一點,任何地方都可以進行自動補齊。
幾乎不需要經常來回看文件。
很少需要回來查看文件。
在這裡,你的編輯器可能會這樣幫助你:
* 在 [Visual Studio Code](https://code.visualstudio.com/) 中:
* 在 [Visual Studio Code](https://code.visualstudio.com/) 中
![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)
* 在 [PyCharm](https://www.jetbrains.com/pycharm/) 中:
* 在 [PyCharm](https://www.jetbrains.com/pycharm/) 中
![editor support](https://fastapi.tiangolo.com/img/pycharm-completion.png)
你將能進行程式碼補齊,這是在之前你可能曾認為不可能的事。例如,請求 JSON body(可能是巢狀的)中的鍵 `price`
你將能進行程式碼補齊,這是在之前你可能曾認為不可能的事。例如,來自請求 JSON body(可能是巢狀的)中的鍵 `price`
這樣比較不會輸錯鍵名,不用來回翻看文件,也不用來回滾動尋找你最後使用的 `username` 或者 `user_name`
### 簡潔 { #short }
FastAPI 為你提供了**預設值**,讓你不必在初期進行繁瑣的配置,一切都可以自動運作。如果你有更具體的需求,則可以進行調整和自定義
它為所有內容提供合理的**預設值**,並且每處都可選擇性設定。所有參數都可以微調,以完成你需要的行為並定義你需要的 API
但預設情況下,一切都「直接可用」。
但預設情況下,一切都 **「直接可用」**
### 驗證 { #validation }
@ -109,47 +109,47 @@ FastAPI 為你提供了**預設值**,讓你不必在初期進行繁瑣的配
* 字串 (`str`) 欄位,定義最小或最大長度。
* 數字 (`int`, `float`) 與其最大值和最小值等。
* 驗證外來的型別,比如:
* URL
* Email
* UUID
* 驗證較特殊的型別,比如:
* URL
* Email
* UUID
* ...等等。
所有的驗證都由完善且強大的 **Pydantic** 處理。
### 安全性及身份驗證 { #security-and-authentication }
FastAPI 已經整合了安全性和身份驗證的功能,但不會強制與特定的資料庫或資料模型進行綁定
FastAPI 已經整合了安全性和身份驗證的功能。不需在資料庫或資料模型上妥協
OpenAPI 中定義的安全模式,包括:
OpenAPI 中定義的所有安全模式,包括:
* HTTP 基本認證。
* **OAuth2**(也使用 **JWT tokens**)。在 [OAuth2 with JWT](tutorial/security/oauth2-jwt.md) 查看教學。
* API 密鑰,在:
* 標頭(Header)
* 查詢參數
* 標頭
* 查詢參數
* Cookies,等等。
加上來自 Starlette(包括 **session cookie**)的所有安全特性。
加上來自 Starlette(包括 **session cookies**)的所有安全特性。
所有的這些都是可重複使用的工具和套件,可以輕鬆與你的系統、資料儲存(Data Stores)、關聯式資料庫(RDBMS)以及非關聯式資料庫(NoSQL)等等整合。
所有的這些都是可重複使用的工具和元件,可以輕鬆與你的系統、資料儲存、關聯式和 NoSQL 資料庫等整合。
### 依賴注入(Dependency Injection) { #dependency-injection }
FastAPI 有一個使用簡單,但是非常強大的 <dfn title='也稱為「components」、「resources」、「services」、「providers」'><strong>依賴注入</strong></dfn> 系統。
* 依賴項甚至可以有自己的依賴,從而形成一個層級或**依賴圖**結構。
* 依賴項甚至可以有自己的依賴,從而形成一個層級或**依賴項的「**結構。
* 所有**自動化處理**都由框架完成。
* 依賴項不僅能從請求中提取資料,還能**對 API 的路徑操作進行強化**,並自動生成文檔
* 即使是依賴項中定義的*路徑操作參數*,也會**自動進行驗證**。
* 支持複雜的用戶身份驗證系統、**資料庫連接**等。
* 不與資料庫、前端等進行強制綁定,但能輕鬆整合它們。
* 所有依賴項都可以從請求中要求資料,並**擴充路徑操作**的限制條件與自動文件
* 即使是依賴項中定義的*路徑操作*參數,也會**自動進行驗證**。
* 支援複雜的使用者身份驗證系統、**資料庫連接**等。
* **不需妥協**資料庫、前端等。但能輕鬆整合它們。
### 無限制「擴充功能」 { #unlimited-plug-ins }
或者說,無需其他額外配置,直接導入並使用你所需要的程式碼
或者說,其實不需要它們,匯入並使用你需要的程式碼即可
任何整合都被設計得非常簡單易用(通過依賴注入),你只需用與*路徑操作*相同的結構和語法,用兩行程式碼就能為你的應用程式建立一個「擴充功能」。
任何整合都被設計得非常簡單易用(通過依賴),你只需用與*路徑操作*相同的結構和語法,用 2 行程式碼就能為你的應用程式建立一個「plug-in」。
### 測試 { #tested }
@ -159,7 +159,9 @@ FastAPI 有一個使用簡單,但是非常強大的 <dfn title='也稱為「co
## Starlette 特性 { #starlette-features }
**FastAPI** 完全相容且基於 [**Starlette**](https://www.starlette.dev/)。所以,你有其他的 Starlette 程式碼也能正常運作。`FastAPI` 實際上是 `Starlette` 的一個子類別。所以,如果你已經知道或者使用過 Starlette,大部分的功能會以相同的方式運作。
**FastAPI** 完全相容且基於 [**Starlette**](https://www.starlette.dev/)。所以,你有其他的 Starlette 程式碼也能正常運作。
`FastAPI` 實際上是 `Starlette` 的一個子類別。所以,如果你已經知道或者使用過 Starlette,大部分的功能會以相同的方式運作。
通過 **FastAPI** 你可以獲得所有 **Starlette** 的特性(FastAPI 就像加強版的 Starlette):
@ -169,31 +171,31 @@ FastAPI 有一個使用簡單,但是非常強大的 <dfn title='也稱為「co
* 支援啟動和關閉事件。
* 有基於 HTTPX 的測試用戶端。
* 支援 **CORS**、GZip、靜態檔案、串流回應。
* 支援 **Session 和 Cookie**
* 支援 **Session 和 Cookie**
* 100% 測試覆蓋率。
* 100% 型別註的程式碼庫。
* 100% 型別註的程式碼庫。
## Pydantic 特性 { #pydantic-features }
**FastAPI** 完全相容且基於 [**Pydantic**](https://docs.pydantic.dev/)。所以,你有其他 Pydantic 程式碼也能正常作。
**FastAPI** 完全相容且基於 [**Pydantic**](https://docs.pydantic.dev/)。所以,你有其他 Pydantic 程式碼也能正常作。
相容包括基於 Pydantic 的外部函式庫,例如用於資料庫的 <abbr title="Object-Relational Mapper - 物件關聯對映器">ORM</abbr>s<abbr title="Object-Document Mapper - 物件文件對映器">ODM</abbr>s。
相容包括同樣基於 Pydantic 的外部函式庫,例如用於資料庫的 <abbr title="Object-Relational Mapper - 物件關聯對映器">ORM</abbr>s<abbr title="Object-Document Mapper - 物件文件對映器">ODM</abbr>s。
這也意味著在很多情況下,你可以把從請求中獲得的物件**直接傳到資料庫**,因為所有資料都會自動進行驗證。
這也意味著在很多情況下,你可以把從請求中獲得的相同物件**直接傳到資料庫**,因為所有資料都會自動進行驗證。
反之亦然,在很多情況下,你也可以把從資料庫中獲取的物件**直接傳給客戶端**。
通過 **FastAPI** 你可以獲得所有 **Pydantic** 的特性(FastAPI 基於 Pydantic 做了所有的資料處理):
* **更簡單**
* 不需要學習新的 micro-language 來定義結構
* **不傷腦筋**
* 不需要學習新的 schema 定義 micro-language。
* 如果你知道 Python 型別,你就知道如何使用 Pydantic。
* 和你的 **<abbr title="Integrated Development Environment - 整合開發環境: 類似於程式碼編輯器">IDE</abbr>/<dfn title="檢查程式碼錯誤的程式">linter</dfn>/brain** 都能好好配合:
* 因為 Pydantic 的資料結構其實就是你自己定義的類別實例,所以自動補齊、linting、mypy 以及你的直覺都能很好地在經過驗證的資料上發揮作用。
* 和你的 **<abbr title="Integrated Development Environment - 整合開發環境類似於程式碼編輯器">IDE</abbr>/<dfn title="檢查程式碼錯誤的程式">linter</dfn>/brain** 都能好好配合:
* 因為 pydantic 的資料結構其實就是你自己定義的類別實例,所以自動補齊、linting、mypy 以及你的直覺都能很好地在經過驗證的資料上發揮作用。
* 驗證**複雜結構**:
* 使用 Pydantic 模型時,你可以把資料結構分層設計,並且用 Python`List``Dict`型別來定義
* 使用階層式 Pydantic 模型、Python `typing``List``Dict` 等。
* 驗證器讓我們可以輕鬆地定義和檢查複雜的資料結構,並把它們轉換成 JSON Schema 進行記錄。
* 你可以擁有深層**巢狀的 JSON** 物件,並對它們進行驗證和註
* **可擴**
* Pydantic 讓我們可以定義客製化的資料型別,或者你可以使用帶有 validator 裝飾器的方法來擴模型中的驗證功能。
* 你可以擁有深層**巢狀的 JSON** 物件,並對它們進行驗證和註
* **可擴**
* Pydantic 讓我們可以定義客製化的資料型別,或者你可以使用帶有 validator 裝飾器的方法來擴模型中的驗證功能。
* 100% 測試覆蓋率。

6
docs/zh-hant/docs/index.md

@ -277,7 +277,7 @@ INFO: Application startup complete.
<details markdown="1">
<summary>關於指令 <code>fastapi dev</code>...</summary>
指令 `fastapi dev` 會讀取你的 `main.py`,偵測其中的 **FastAPI** 應用,並使用 [Uvicorn](https://www.uvicorn.dev) 啟動伺服器。
指令 `fastapi dev`自動讀取你的 `main.py`,偵測其中的 **FastAPI** 應用,並使用 [Uvicorn](https://www.uvicorn.dev) 啟動伺服器。
預設情況下,`fastapi dev` 會在本機開發時啟用自動重新載入。
@ -473,7 +473,7 @@ item: Item
![editor support](https://fastapi.tiangolo.com/img/vscode-completion.png)
若想看包含更多功能的完整範例,請參考 <a href="https://fastapi.tiangolo.com/zh-hant/tutorial/">Tutorial - User Guide</a>
若想看包含更多功能的完整範例,請參考 <a href="https://fastapi.tiangolo.com/zh-hant/tutorial/">教學 - 使用者指南</a>
**劇透警告**:教學 - 使用者指南包含:
@ -520,7 +520,7 @@ CLI 會自動偵測你的 FastAPI 應用並將其部署到雲端。若你尚未
它把用 FastAPI 開發應用的**開發者體驗**帶到**部署**到雲端的流程中。🎉
FastAPI Cloud 是「FastAPI 與好朋友們」這些開源專案的主要贊助與資金來源。✨
FastAPI Cloud 是 *FastAPI 與好朋友們* 這些開源專案的主要贊助與資金來源。✨
#### 部署到其他雲端供應商 { #deploy-to-other-cloud-providers }

38
docs/zh-hant/docs/python-types.md

@ -2,11 +2,11 @@
Python 支援可選用的「型別提示」(也稱為「型別註記」)。
這些「型別提示」或註記是一種特殊語法,用來宣告變數的<dfn title="例如:str、int、float、bool">型別</dfn>
這些 **「型別提示」** 或註記是一種特殊語法,用來宣告變數的<dfn title="例如:str、int、float、bool">型別</dfn>
為你的變數宣告型別後,編輯器與工具就能提供更好的支援。
這裡只是關於 Python 型別提示的快速教學/複習。它只涵蓋使用在 **FastAPI** 時所需的最低限度...其實非常少。
這裡只是關於 Python 型別提示的**快速教學/複習**。它只涵蓋使用在 **FastAPI** 時所需的最低限度...其實非常少。
**FastAPI** 完全是以這些型別提示為基礎,並因此帶來許多優勢與好處。
@ -137,7 +137,7 @@ John Doe
### `typing` 模組 { #typing-module }
在一些其他情境中,你可能需要從標準程式庫的 `typing` 模組匯入一些東西,比如當你想宣告某個東西可以是「任何型別」時,可以用 `typing` 裡的 `Any`
在一些其他情境中,你可能需要從標準程式庫的 `typing` 模組匯入一些東西,比如當你想宣告某個東西可以是「任何型別」時,可以用 `Any`
```python
from typing import Any
@ -151,7 +151,7 @@ def some_function(data: Any):
有些型別可以在方括號中接收「型別參數」,以定義其內部元素的型別,例如「字串的 list」可以宣告為 `list[str]`
這些能接收型別參數的型別稱為「泛型(Generic types)」或「Generics」
這些能接收型別參數的型別稱為 **泛型(Generic types)****Generics**
你可以將相同的內建型別用作泛型(使用方括號並在裡面放型別):
@ -221,7 +221,7 @@ def some_function(data: Any):
#### Union { #union }
你可以宣告一個變數可以是「多種型別」中的任一種,例如 `int``str`
你可以宣告一個變數可以是**多種型別**中的任一種,例如 `int``str`
要這麼定義,你使用<dfn title='也稱為「位元或運算子」,但在這裡與該含義無關'>豎線(`|`)</dfn>來分隔兩種型別。
@ -263,9 +263,9 @@ def some_function(data: Any):
<img src="/img/python-types/image06.png">
請注意,這表示「`one_person` 是類別 `Person`『實例(instance)』」。
請注意,這表示「`one_person` 是類別 `Person`**實例(instance)**」。
並不是「`one_person` 就是名為 `Person`『類別(class)』」。
並不是「`one_person` 就是名為 `Person`**類別(class)**」。
## Pydantic 模型 { #pydantic-models }
@ -295,7 +295,7 @@ def some_function(data: Any):
## 含中繼資料的型別提示 { #type-hints-with-metadata-annotations }
Python 也有一個功能,允許使用 `Annotated` 在這些型別提示中放入額外的<dfn title="關於資料的資料;在此情境下,是關於型別的資訊,例如描述。">中繼資料</dfn>
Python 也有一個功能,允許使用 `Annotated` 在這些型別提示中放入**額外的<dfn title="關於資料的資料;在此情境下,是關於型別的資訊,例如描述。">中繼資料</dfn>**
你可以從 `typing` 匯入 `Annotated`
@ -305,15 +305,15 @@ Python 本身不會對這個 `Annotated` 做任何事。對編輯器與其他工
但你可以利用 `Annotated` 這個空間,來提供 **FastAPI** 額外的中繼資料,告訴它你希望應用程式如何運作。
重要的是要記住,傳給 `Annotated`「第一個型別參數」才是「真正的型別」。其餘的,都是給其他工具用的中繼資料。
重要的是要記住,傳給 `Annotated`**第一個*型別參數***才是**實際型別**。其餘的,都是給其他工具用的中繼資料。
目前你只需要知道 `Annotated` 的存在,而且它是標準的 Python。😎
之後你會看到它有多「強大」
之後你會看到它有多**強大**
/// tip | 提示
因為這是「標準 Python」,所以你在編輯器、分析與重構程式碼的工具等方面,仍然能獲得「最佳的開發體驗」。✨
因為這是**標準 Python**,所以你在編輯器、分析與重構程式碼的工具等方面,仍然能獲得**最佳的開發體驗**。✨
而且你的程式碼也會與許多其他 Python 工具與程式庫非常相容。🚀
@ -325,17 +325,17 @@ Python 本身不會對這個 `Annotated` 做任何事。對編輯器與其他工
**FastAPI** 中,你用型別提示來宣告參數,然後你會得到:
* 編輯器支援
* 型別檢查
* **編輯器支援**
* **型別檢查**
...而 **FastAPI** 也會用同樣的宣告來:
* 定義需求:來自請求的路徑參數、查詢參數、標頭、主體(body)、相依性等
* 轉換資料:把請求中的資料轉成所需型別
* 驗證資料:來自每個請求的資料:
* 當資料無效時,自動產生錯誤並回傳給用戶端
* 使用 OpenAPI 書寫 API 文件
* 之後會由自動的互動式文件介面所使用
* **定義需求**:來自請求的路徑參數、查詢參數、標頭、主體(body)、相依性等
* **轉換資料**:把請求中的資料轉成所需型別
* **驗證資料**:來自每個請求的資料:
* 當資料無效時,產生回傳給用戶端的**自動錯誤**。
* 使用 OpenAPI **記錄** API
* 之後會由自動的互動式文件介面所使用
這些現在聽起來可能有點抽象。別擔心。你會在[教學 - 使用者指南](tutorial/index.md)中看到它們的實際運作。

10
docs/zh-hant/docs/virtual-environments.md

@ -73,7 +73,7 @@ $ python -m venv .venv
</div>
/// details | 上述令的含義
/// details | 上述令的含義
* `python`: 使用名為 `python` 的程式
* `-m`: 以腳本的方式呼叫一個模組,我們將告訴它接下來使用哪個模組
@ -106,7 +106,7 @@ $ uv venv
////
這個令會在一個名為 `.venv` 的目錄中建立一個新的虛擬環境。
這個令會在一個名為 `.venv` 的目錄中建立一個新的虛擬環境。
/// details | `.venv`,或是其他名稱
@ -164,7 +164,7 @@ $ source .venv/Scripts/activate
/// tip
每次你在這個環境中安裝一個**新的套件**時,都需要**重新啟動**這個環境。
每次你在這個環境中安裝一個**新的套件**時,都需要**再次啟用**這個環境。
這麼做確保了當你使用一個由這個套件安裝的**終端(<abbr title="command line interface - 命令列介面">CLI</abbr>)程式**時,你使用的是你的虛擬環境中的程式,而不是全域安裝、可能版本不同的程式。
@ -242,7 +242,7 @@ $ python -m pip install --upgrade pip
</div>
/// tip | 注意
/// tip
有時你在嘗試升級 pip 時,可能會遇到 **`No module named pip`** 的錯誤。
@ -544,7 +544,7 @@ Python 套件在推出**新版本**時通常會儘量**避免破壞性更改**
現在,想像一下如果有**許多**其他**套件**,它們都是你的**專案所依賴的**。這樣是非常難以管理的。你可能會發現有些專案使用了一些**不相容的套件版本**,而無法得知為什麼某些程式無法正常運作。
此外,取決於你的作系統(例如 Linux、Windows、macOS),它可能已經預先安裝了 Python。在這種情況下,它可能已經有一些系統所需的套件和特定版本。如果你在全域 Python 環境中安裝套件,可能會**破壞**某些隨作業系統一起安裝的程式。
此外,取決於你的作系統(例如 Linux、Windows、macOS),它可能已經預先安裝了 Python。在這種情況下,它可能已經有一些系統所需的套件和特定版本。如果你在全域 Python 環境中安裝套件,可能會**破壞**某些隨作業系統一起安裝的程式。
## 套件安裝在哪裡 { #where-are-packages-installed }

Loading…
Cancel
Save