資安宣導 — 為什麼使用 PyYaml 解析 YAML 時要使用 safe_load 才對
對於任何來自未受信任來源的資料,我們都必須假設它可能含有惡意的內容。
就連 YAML 檔也是一樣的!
Posted on Jan 15, 2024 in Python 程式設計 - 中階 , Python 資訊安全 by Amo Chen ‐ 1 min read
對於任何來自未受信任來源的資料,我們都必須假設它可能含有惡意的內容。
就連 YAML 檔也是一樣的!
Posted on Jan 15, 2024 in Python 程式設計 - 中階 , Python 資訊安全 by Amo Chen ‐ 1 min read
__slots__
是 Python 類別必須認識的屬性,這個屬性為我們帶來節省記憶體資源以及增加存取(access)類別屬性(attribute)效率的好處,但相對地,它也犧牲原本方便擴充類別屬性的易用性。
總的來說,它是寫出高效率 Python 程式碼的一環,平常用不到它沒有關係,但如果要榨出更多記憶體資源以及效能的話, __slots__
是一定能派上用場。
本文將透過各種範例認識 __slots__
並學會如何運用它。
Posted on Oct 16, 2023 in Python 程式設計 - 中階 by Amo Chen ‐ 4 min read
Python 的物件導向程式設計(OOP)有 2 個一定要懂的東西:
如果不懂得這 2 個東西,就無法徹底解放類別(class)的力量,甚至可能導致寫出不夠彈性而且冗長的程式碼。
super() + MRO
= 超級瑪利歐?(誤
本文將從 super()
函式開始講解,說明 Python 的 MRO(Method Resolution Order) ,並介紹 MRO 的特性在實務上的應用。
如果你無法正確回答以下範例結果的執行結果,那麽推薦你看完本文:
class Parent(object):
NAME = 'Parent'
def __str__(self):
return self.NAME
class Child(Parent):
NAME = 'Child'
def __str__(self):
return super().__str__()
c = Child()
print(c)
正確答案為: Child
Posted on Oct 6, 2023 in Python 程式設計 - 中階 by Amo Chen ‐ 6 min read
Python 3.8 之後 typing 模組 新增 1 個 typing.Protocol 的 class 可以使用,這個 class 很適合用來給一些有實作特定方法的 class 們做 type annotation 。
舉個常見的交通工具作為例子,假設我們有 1 個函數接受任何有實作 move()
方法的 instance:
def move(x):
x.move()
這時候可以用 typing.Protocol 將參數 x
加上 1 個 type hint, 讓彼此知道此處不管型別,只管是否有實作 move()
方法:
from typing import Protocol
class Movable(Protocol):
def move(self):
...
def move(x: Movable):
x.move()
加上 typing.Protocol 是否看起來清晰很多?
Posted on Sep 25, 2023 in Python 程式設計 - 中階 by Amo Chen ‐ 4 min read
大家都知道執行緒(Threads)之間會共用 Process 的記憶體,這種共用的情況有可能造成 Race Condition, 使得程式出現不可預期的行為或錯誤,所幸這個問題可以透過 threadling.local 解決。
而 Python 3.4 之後推出 asyncio 模組,使得 Python 具備執行非同步 I/O (asynchronous I/O) 的能力,開發者可以同時結合 multiprocessing , threading 以及 asyncio 將 Python 效能提升至全新檔次,但是當結合 threading 以及 asyncio 時,可能會遭遇一個問題, 多個協程(coroutines)可能會在同 1 個執行緒中執行,因此多個 coroutines 也可能有互相影響的情況!所以有了 contextvars 模組,用以解決 coroutines 互相干擾的情況,將每個 coroutine 以 Context 切開,避免互相干擾!
Thread-local variables are insufficient for asynchronous tasks that execute concurrently in the same OS thread. Any context manager that saves and restores a context value using threading.local() will have its context values bleed to other code unexpectedly when used in async/await code.
Posted on Sep 21, 2023 in Python 程式設計 - 高階 by Amo Chen ‐ 4 min read
不可否認 Python 以其優異的生態系與社群資源為開發帶來速度優勢。
不過每個應用都有效率極限, Python 當然也不例外,而且 Python 天生比起 JavaScript, Java 等語言更容易遇到效能瓶頸,這時候通常有 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
這陣子做記憶體用量相關的研究時,就在想怎麼視覺化(visualize) Python 執行時隨時間變化的記憶體用量,當然,步驟越簡單越好。
查了才知道,知名的 memory_profiler 已經把這件事情搞定。
一起來看怎麼畫 Python 記憶體用量圖吧!
Posted on Sep 11, 2023 in Python 模組/套件推薦 , Python 程式設計 - 中階 by Amo Chen ‐ 2 min read
我們都知道多個執行緒(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