赛博红兔的科技博客

CyberHongTu shares news, insights, and musings on fascinating technology subjects.


和我一起玩Python:39. 行鸭即鸭和先行后礼

大家好,我是赛博红兔。上集我们聊了如何让我们的Python代码更加Pythonic,也就是具有Python的风格。没看过的小伙伴赶紧去看看38集。今天,我们将补充如何做到Pythonic风格。学Python的圈子里常提到两个概念:“Duck Typing”和“Easier to Ask for Forgiveness than Permission (EAFP)”。我将其翻译为“行鸭即鸭”和“先行后礼”。

这两个概念关系紧密,所以我准备在同一个视频里讲解。首先,我们来看看什么是Duck Typing。在Python里,如果一个对象走路像鸭子,叫声像鸭子,那么它就是鸭子。意思是,我们不关心对象的类型,只关心它能否完成要求的任务。举个例子:

class Duck:
    def quack(self):
        print("嘎!嘎!")
    def fly(self):
        print("噗!噗!")

class Person:
    def quack(self):
        print("我在学鸭叫!")
    def fly(self):
        print("我在扑腾手臂飞行!")

def quack_and_fly(thing):
    if isinstance(thing, Duck):
        thing.quack()
        thing.fly()
    else:
        print("这不是一只鸭子!")

duck = Duck()
person = Person()
quack_and_fly(duck)
quack_and_fly(person)

在这个例子中,我们有两个类:鸭子和人类。两者都有“叫”和“飞”的方法。函数quack_and_fly需要一个对象并尝试运行“叫”和“飞”方法。传统方法会检查对象类型,而Duck Typing则直接尝试调用方法。

接下来是EAFP,即先行后礼。不同于“Look before you leap(LBYL)”,EAFP先尝试执行操作,遇到错误再处理。比如:

def quack_and_fly(thing):
    try:
        thing.quack()
        thing.fly()
        thing.bark()
    except AttributeError as e:
        print(e)

这种方法不检查对象属性,而是直接尝试调用方法,出错则捕获异常。

实际应用中也是如此,比如读取文件:

import os

# LBYL写法
def read_file(filename):
    if os.path.exists(filename):
        with open(filename, 'r') as file:
            return file.read()
    else:
        return "File not found."

# EAFP写法
def read_file(filename):
    try:
        with open(filename, 'r') as file:
            return file.read()
    except FileNotFoundError:
        return "File not found."

EAFP风格直接尝试读取文件,出错则处理异常,提高性能和可读性。



Leave a comment