Python 程式設計 - 高階

Python 套件推薦 - rustimport 給你的 Python 一對翅膀

不可否認 Python 以其優異的生態系與社群資源為開發帶來速度優勢。

不過每個應用都有效率極限, Python 當然也不例外,而且 Python 天生比起 JavaScript, Java 等語言更容易遇到效能瓶頸,這時候通常有 3 種選擇:

  1. 改用效率較好的寫法或套件
  2. 部分功能/元件改用別的語言實作
  3. 全部用別的語言實作

選項 1 是最簡單的,只要能夠找到更快的寫法或者更好的套件,就能夠緩解問題,再撐一陣子;選項 3 則是最困難的,要有足夠的時間以及負責人的支持之下,才有可能進行,畢竟所有的功能都必須改寫之外,測試也是需要全部重新來過,更何況通常公司專案都有時程壓力,選項 3 通常都是難以說服高層的選項;至於選項 2 則是折衷選項,建議選項 1 已經無法解決問題時採用,目前很多 Python 套件為了效率也都會採用選項 2 的做法,例如 orjson 就是以 Rust 語言實作的 JSON parser 。

目前 Python 與 Rust 的介接主要靠 PyO3 , 不過步驟稍微複雜一些,本文將介紹如何透過 rustimport 套件,極度簡化介接 Python 與 Rust 的方法,讓開發 Python 擴充套件可以更快樂、簡便!

Posted on  Sep 18, 2023  in  Python 模組/套件推薦 , Python 程式設計 - 高階  by  Amo Chen  ‐ 4 min read

Python threading.local() 解說

我們都知道多個執行緒(thread)之間會共用 Process 的記憶體,那你覺得以下範例程式的執行結果會是什麼呢?這是 2 個執行緒分別做 +1 與 -1 運算各 100,000 次的 Python 程式:

import threading


def count(thread_name, step=1):
    global v
    for i in range(0, 100000):
        v += 1 * step
    print(f'{thread_name} -> ', v, flush=True)


v = 0
t1 = threading.Thread(target=count, args=('t1', 1, ))
t2 = threading.Thread(target=count, args=('t2', -1, ))
t1.start()
t2.start()
t1.join()
t2.join()

這段範例程式的執行結果,就跟本文要解說的 threading.local() 有關。

Posted on  Sep 4, 2023  in  Python 程式設計 - 高階  by  Amo Chen  ‐ 3 min read

零經驗也可的 PySpark 教學 - 資料輸出 (DataFrame writer)

通常操作 dataframe 完之後,都會需要將結果輸出到資料庫/檔案甚至是雲端服務。 PySpark 已經將相關的輸出都整合到 pyspark.sql.DataFrameWriter 類別,只要理解該類別,基本上就能夠輕鬆將 DataFrame 輸出。

本文將介紹 pyspark.sql.DataFrameWriter 以及幾個使用上值得注意的點。

Posted on  Feb 6, 2023  in  Python 模組/套件推薦 , Python 程式設計 - 高階  by  Amo Chen  ‐ 4 min read

優化 Python Docker Image Size - 從 multi-stage builds 到 distroless

Docker multi-stage builds 教學 一文介紹以 Golang 作為範例,示範如何用 Docker multi-stage builds 的功能,優化編譯 Docker image 的過程,以減少 Docker Image 的 size 。

Multi-stage builds 並不局限於 Golang 這類的編譯(compiled)語言才能使用,腳本(script)語言也能夠運用類似的技巧降低 Docker image size, 例如 Javascript, Python 等開發生態系也都能夠使用。

只是腳本語言需透過直譯器(interpreter)執行的天性,因此其 Docker image 終究難以像 Golang 這類編譯語言所產生的 image 來得小,但這並不代表 Python, Javascript 這類的 Docker image 並不值得使用 multi-stage builds, 優化 Docker image size 仍可以為部署(deployment)速度帶來優勢,同時也能減少網路傳輸所需付出的費用成本。

本文的 multi-stage builds 以 Python 範例出發,一路介紹到如何使用 Google 所提供 distroless 進一步優化 Docker image size 與安全性。

Posted on  Jan 6, 2023  in  Docker , Python 程式設計 - 高階  by  Amo Chen  ‐ 5 min read

零經驗也可的 PySpark 教學 - UDF (User Defined Function)

Spark SQL 提供許多好用的函式(functions),例如 concat() , count() , date_format() 等等,但這些內建函式不一定能夠滿足一切的需求,所以有時候需要做一些擴充以達到目的,此種讓使用者能夠進行擴充的功能就被稱為 UDF (User Defined Function), RDBMS 諸如 MySQL 與 PostgreSQL 等也都支援 UDF, 詳見:

  1. MySQL - Adding a Loadable Function
  2. PostgreSQL - User-Defined Functions

Spark 也同樣支援 UDF, 讓使用者能夠擴充函式。

Posted on  Dec 28, 2022  in  Python 模組/套件推薦 , Python 程式設計 - 高階  by  Amo Chen  ‐ 4 min read

零經驗也可的 PySpark 教學 - DataFrame part 1

上一篇 零經驗也可的 PySpark 教學 - 初體驗 ,我們透過 Docker 輕易地體驗到 PySpark 的功能,利用 PySpark 將 CSV 資料載入 DataFrame ,再將 DataFrame 轉成 temporary view 後,我們就能夠使用 SQL 對資料進行操作,過程相當輕鬆寫意。

不過 DataFrame 提供相當多的 API, 讓開發者能夠像操作 ORM(Object Relational Mapping) 一樣進行開發,可說是 PySpark 學習過程必須學會的一環,本篇將介紹更多關於 DataFrame 的相關操作,包含 SELECT, FILTER, JOIN, UNION 等常用的功能。

Last updated on  Dec 16, 2022  in  Python 模組/套件推薦 , Python 程式設計 - 高階  by  Amo Chen  ‐ 6 min read