[Effective Python笔记]二、函数

尽量用异常来表示特殊情况,而不要返回None

有时候我们编写函数时,会喜欢给None这个返回值特殊意义。这种做法在某些情况下是合理的,例如,计算两数相除的商,在除数为0的时候,计算结果是没有明确含义的(undefined),所以似乎应该返回None。

def divide(a, b):
    try:
        return a/b
    except ZeroDivisionError:
        return None

但是我们在拿到这个返回值做判断时,往往不会专门去判断函数的返回值是否为None,而是会假定:只要返回了与False等效的运算结果,就说明函数出错了。

x, y = 0, 5
result = divide(x, y)
if not result:
    print("Invalid inputs") # This is wrong!

如果None这个返回值具备特殊意义,可能会使调用它的人写出错误的代码。有两种办法可以减少这个错误。
第一种办法,把返回值拆成两部分放到二元组(two-tuple)里。二元组的首个元素,表示操作是否成功,第二个元素,才是真正的运算结果。

def divide(a, b):
    try:
        return True, a/b
    except ZeroDivisionError:
        return False, None

这样做的问题在于,调用者可以用下划线为名称的变量,跳过元组的第一部分。这样写没错,但是却和返回None有着相似的错误。
第二种办法好一些,那就根本不返回None,把错误抛给上一级,让调用者必须处理它。

def divide(a, b):
    try:
        return a/b
    except ZeroDivisionError as e:
        raise ValueError("Invalid inputs") from e

这样写出来的代码,会比较清晰。

了解如何在闭包里使用外围作用域的变量

假如有一份列表,其中的元素全是数字,现在我们要对其排序,排序时要把出现在某个群组内的数字,放在群组外数字之前。
实现这个功能的常见用法是使用sort排序,把辅助函数传给key参数。

def sort_priority(values, group):
    def helper(x):
        if x in group:
            return (0, x)
        return (1, x)
    values.sort(key=helper)

用这个函数应对一些简单的输入值。

numbers = [8, 3, 1, 2, 5, 4, 7, 6]
group = {
   2, 3, 5, 7}
sort_priority(numbers, group)
print(numbers)
>>>
[2, 3, 5, 7, 1, 4, 6, 8]

这个函数能够运行的原因基于下列三个原因:

  • Python支持闭包(closure):闭包是一种定义在某个作用域中的函数,函数引用了那个作用域中的变量。
  • Python的函数是一级对象,我们可以直接引用函数、把函数赋给变量、把函数当成参数传给其它函数,并通过表达式及if语句对其进行比较和判断。
  • Python使用特殊的规则来判断两个元组。它首先比较各元组中下标为0的元素,如果相等,再比较下标为1的元素,依次类推。

现在我们增加一个小需求,如果列表中出现了优先级更高的元素,我们希望sort_priority函数返回一个值,该函数的调用者,可以根据这个值作出相应地功能。
我们先试试下面这种简单的写法:

def sort_priority2(numbers, group):
    found = False
    def helper(x):
        if x in group:
            found = True
            return (0, x)
        return (1, x)
    values.sort(key=helper)
    return found

用刚才输入的值,来运行这个函数。

numbers = [8, 3, 1, 2, 5, 4, 7, 6]
group = {
   2, 3, 5, 7}
found = sort_priority2(numbers, group)
print("Found:", found)
print
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值