云计算百科
云计算领域专业知识百科平台

何为Pythonic?(Beautiful is better than ugly.(优美胜于丑陋) Explicit is better than implicit.(明了胜于晦涩) Simple)

Pythonic——“地道”的python代码

当你开始深入 Python 的世界时,你一定会频繁听到一个词:"Pythonic"。

在其他编程语言中,我们通常只关注代码是否能“跑通”。但在 Python 社区,代码能运行只是最低标准,我们追求的是代码写得 "Pythonic"。

那么,到底什么是 Pythonic?

简单来说,Pythonic 是指代码遵循 Python 的设计理念和惯用手法。它意味着你的代码简洁、明确、可读性强,并且充分利用了 Python 语言独有的特性,而不是生搬硬套 C、Java 或其他语言的逻辑。

写出 Pythonic 的代码,不仅能让你的程序更优雅,通常还能带来更高的执行效率和更低的维护成本。

从实例看 Pythonic

1,变量交换

啰嗦且丑陋的

temp = a
a = b
b = temp

简洁且优雅的

Python 支持元组拆包(Tuple Unpacking),这使得交换变得极其直观。

a, b = b, a

2,循环遍历

啰嗦且复杂的

numbers = [1, 2, 3, 4, 5]
squares = []
for n in numbers:
if n % 2 == 0:
squares.append(n**2)

简洁且直观的

列表推导式是 Python 最强大的特性之一,它将循环和条件判断浓缩为一行,读起来像英语句子一样流畅。

numbers = [1, 2, 3, 4, 5]
squares = [n**2 for n in numbers if n % 2 == 0]

怎么才能写出优雅的Pythonic风格代码?

像使用内置类型一样使用自定义对象!

内置类型,指的就是诸如序列(列表)、映射(字典)等的Python内置类型,我们要让我们自己定义的对象像这些内置对象一样使用。比如一个字典可以这样取值value = map["key"],列表可以使用nums[1:2]进行切片。怎么让我们自己定义的对象也可以像python的内置对象一样有这些操作呢?答案就是,实现魔法方法!我们可以把Python当成一个框架,我们去实现各种魔法方法,让我们的代码更加Pythonic!

什么是魔法方法?魔法方法(Magic Methods)是Python中特殊的方法,以双下划线开头和结尾(如 __init__),也被称为双下方法(Dunder Methods)。它们让Python对象能够实现特定的语言特性。

实现一个简单的购物车

1,非Pythonic写法,类似Java风格的代码

class JavaStyleCart:
def __init__(self):
self.items = []

# 添加元素
def add_item(self, item):
self.items.append(item)

# 获取长度
def get_item_count(self):
return len(self.items)

# 通过索引获取元素
def get_item_at(self, index):
return self.items[index]

# — 使用时 —
cart = JavaStyleCart()
cart.add("Apple")
cart.add("Banana")
cart.add("Orange")
cart.add("Strawberry")
cart.add("Peach")

# 痛点 1:每次用都要查文档,到底哪个方法获取长度?
print(f"购物车有 {cart.get_item_count()} 件商品")

# 痛点 2:想遍历?不能直接用 for 循环,得自己写 range
for i in range(cart.get_item_count()):
print(cart.get_item_at(i))

# 如果想拿到第二到第四个商品,非常痛苦
items_2_to_4 = [
cart.get_item_at(1), # 第二个商品
cart.get_item_at(2), # 第三个商品
cart.get_item_at(3) # 第四个商品
]
print(items_2_to_4)

可以发现代码及其冗长且不优雅,一点都不Pythonic!我们无法像使用内置类型一样优雅地使用我们的购物车,而且他的功能也仅限于我们定义的方法。

2,Pythonic风格的写法

class PythonicCart:
def __init__(self):
self.items = []

def add(self, item):
self.items.append(item)

# 实现这个,len() 就能用了
def __len__(self):
return len(self.items)

# 实现这个,切片、索引、迭代就全通了
def __getitem__(self, position):
return self.items[position]

# — 使用时 —
cart = PythonicCart()
cart.add("Apple")
cart.add("Banana")
cart.add("Orange")
cart.add("Strawberry")
cart.add("Peach")

# 不需要查文档,想知道长度直接用 len(),这是肌肉记忆
print(f"购物车有 {len(cart)} 件商品")

# 自动支持 for 循环,因为实现了 __getitem__
for item in cart:
print(item)

# 直接使用切片
print(f"第二到第四个商品 {cart[1:4]}")

# 实现了__len__和__getitem__之后,我们发现我们还获得了其他的能力!
# 如随机获取一个幸运商品
# 为什么实现了这两个魔法方法之后我们就可以使用随机获取这个方法了呢
# 这涉及到了Python中的协议(Protocol),后续会有单独文章讲解
import random
lucky_item = random.choice(cart)
print(f"抽奖结果是 {lucky_item }")

我们只需要简单地实现这个“框架”中__len__和__getitem__这两个接口,我们的cart就获得了强大的能力!因为我们实现了python这个框架定义的接口。Python解释器会在背后偷偷帮我们调用这些被我们实现了的魔法方法!

借助魔法方法,自定义对象的行为可以像内置类型语言,让我们写出更具表现力的代码,符合Python社区所认可的Python风格。Python中还有许多其他的魔法方法,读者们可以自己去了解,本文因为篇幅有限,只是做了一个简单的举例。例如读者们可以根据上面购物车的例子,探索一下怎么让购物车可以直接使用+运算符从而将两个购物车的内容相加。

赞(0)
未经允许不得转载:网硕互联帮助中心 » 何为Pythonic?(Beautiful is better than ugly.(优美胜于丑陋) Explicit is better than implicit.(明了胜于晦涩) Simple)
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!