一些 Python 的奇技淫巧
Kingsley1116 · · 科技·工程
引入
提到 Python,多数人会先想到它「简洁易读」的语法、「万物皆物件」 的设计,或是在资料分析、爬虫、AI 领域里开箱即用的丰富函式库。但很少有人注意到,这门语言还藏着许多「不走寻常路」的巧思。
(叠个甲,我在澳门 Python 解难大赛拿过冠军)
1. 海象运算符 (:=)
海象运算符允许你在表达式中进行赋值,简化重复计算或赋值。
if (data := get_data()) is not None: # 賦值並檢查
process(data)
2. 实现泛型函数
functools 中的 singledispatch 允许根据第一个参数的类型来分派不同的函数实现。
from functools import singledispatch
@singledispatch
def better_print(obj):
return f"Unknown type: {obj}"
@better_print.register
def _(obj: int):
return f"Integer: {obj}"
@better_print.register
def _(obj: list):
return f"List with {len(obj)} items: {obj}"
print(better_print(10)) # 輸出:Integer: 10
print(better_print([1,2])) # 輸出:List with 2 items: [1, 2]
print(better_print("hi")) # 輸出:Unknown type: hi
3. 使用 ...(Ellipsis) 作为占位符
def unfinished_function():
... # TODO: 實作這個函數
4. 解包
-
合并字典 / 列表:
dict1 = {"a": 1} dict2 = {"b": 2} merged = {**dict1, **dict2} print(merged) # 輸出:{'a': 1, 'b': 2} -
提出元素
first, *middle, last = [1, 2, 3, 4, 5] print(first) # 輸出:1 print(middle) # 輸出:[2, 3, 4] print(last) # 輸出:5 -
拆解列表 / 元组作为位置参数
def add(a, b, c): return a + b + c
nums = [1, 2, 3] print(add(*nums)) # 輸出:6
- 拆解字典作为关键字参数
```py
params = {"a": 10, "b": 20, "c": 30}
print(add(**params)) # 輸出:60
5. 利用 __slots__ 优化记忆体使用
预设情况下,Python 类的实例使用字典 (__dict__) 来储存属性,这提供了灵活性但消耗较多记忆体。 __slots__ 允许你预先声明实例拥有的属性名称,避免创建 __dict__,从而显著减少记忆体开销。
class Point:
__slots__ = ("x", "y") # 只允許有 x 和 y 屬性
def __init__(self, x, y):
self.x = x
self.y = y
p = Point(3, 4)
p.z = 5 # AttributeError
6. 利用字典的 __missing__ 方法实现自动键值生成
当访问字典中不存在的键时,除了用 get() 或 setdefault(),你还可以自订一个类,覆写 __missing__ 方法来动态生成预设值。
class AutoVivifyDict(dict):
def __missing__(self, key):
# 當 key 不存在時,自動建立一個新的空字典作為值
new_dict = {}
self[key] = new_dict
return new_dict
data = AutoVivifyDict()
data["a"]["b"] = 42
print(data) # 輸出:{'a': {'b': 42}}
7. 链式比较
x = 5
if 0 < x < 10: # 等價 x > 0 and x < 10
print("x is between 0 and 10")
结语
善用这些技巧,可以让你的 Python 化码更加优雅、高效;滥用它们,则可能创造出难以维护的「屎山」。
希望这篇文章能给你带来启发!
你对哪个技巧最感兴趣?或者你还知道哪些更「奇淫」的技巧?欢迎分享!