Python重构(二)

前言

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理。

PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取

python免费学习资料、代码以及交流解答点击即可加入


编写干净的,Python式的代码就是要尽可能地使其易于理解,但又要简明扼要。以下是有关Python重构的系列文章的第二部分,第一部分见Python代码重构(一)

本系列的重点是为什么这样做是好的做法,而不仅仅是教你如何做。

1. 将for循环转为list/set/dictionary生成式/推导式(List Comprehensions)

编码的时候我们经常要创建集合。在大多数语言中,标准的做法如下:

values = []
for i in range(20):
    values.append(i ** 3)

在这里我们创建一个数据集列表values,用数字迭代的填充它。在Python中,我们可以访问列表生成式。这样可以在一行上做相同的事情,消除了声明一个空列表然后赋值的麻烦:

values = [i ** 3 for i in range(20)]

我们已经将三行代码转换为一行代码,这绝对是一种胜利——这意味着在阅读方法时减少了来回滚动,并有助于保持代码的可管理性。

将代码压缩到一行可能会更难以阅读,但对于理解来说并非如此。需要的所有元素都很好地呈现出来,并且一旦习惯了这种语法,它实际上比for循环版本更具可读性。

另一点是,赋值现在更像是一个原子操作——我们在声明什么是values,而不是提供关于如何构建它的说明。这使代码读起来更像是一种叙述,因此今后我们更关注values是什么,而不是它的构造细节。

最后,列表生成式的执行通常比在循环中构建集合更快,这是另一个考虑性能的因素。

2. 用增强赋值替代赋值

增强赋值是Python的一个简便语法,比如下面的代码

count = count + other_value

可以替换成下面的代码:

count += other_value

这样代码更短更清晰——我们不需要两次考虑count变量。其他可以使用的操作符包括-=、=、/=和*=。需要注意的一点是,要赋值的类型必须定义适当的操作符。例如,numpy数组不支持/=操作。

3. 内联变量只使用一次

在代码中经常看到给结果变量赋值,然后立即返回它。

def method(self):
    state = {
        code: self.code_format,
        change: self.changed_by,
    }
    return state

这里最好直接返回结果

def method(self):
    return {
        code: self.code_format,
        change: self.changed_by,
    }

这缩短了代码并删除了一个不必要的变量,减少了读取函数的心理负担(mental load)。

临时变量可能有用的地方是,如果它们被用作参数或条件,名称可以当做变量所代表的内容的注释。在从函数返回它的情况下,函数名告诉你结果是什么——在上面的例子中,它是状态属性,而state名没有提供任何额外的信息。

4. 用if表达式替换if语句

根据某些程序状态,通常需要将一个变量设置为两个不同值中的一个。

if condition:
    x = 1
else:
    x = 2

可以使用Python的条件表达式语法(它的三元操作符版本)将其写在一行上:

x = 1 if condition else 2

这肯定更简洁,但它是最有争议的重构之一(也包括列表推是)。一些程序员不喜欢这些表达式,并且发现解析它们比完全写出它们要稍微难一些。

我们的观点是,只要条件表达式很短,并且适合在一行中,它就是一种改进。只有一条语句定义了x,而不是必须读取两个语句加上if-else行。

5. 用生成器替换不必要的推导式

一个小技巧是像any、all和sum这样的函数允许传入生成器而不是集合。这意味着与其这样做:

hat_found = any([is_hat(item) for item in wardrobe])

你可以这样写:

hat_found = any(is_hat(item) for item in wardrobe)

上述代码删除了一对括号,使意图更加清晰。如果找到了hat,它将立即返回,而不必构建整个列表。这种延迟计算可以提高性能。

请注意,我们实际上是在向any()传递一个生成器,所以严格地说,代码应该是这样的:

hat_found = any((is_hat(item) for item in wardrobe))

但是Python允许忽略这对括号。接受生成器的标准库函数有:
'all', 'any', 'enumerate', 'frozenset', 'list', 'max', 'min', 'set', 'sum', 'tuple'

6. 将条件简化为返回语句

最后一个重构是我们希望一个方法的末尾返回True或False。一种常见的方法是这样的:

def function():
    if isinstance(a, b) or issubclass(b, a):
        return True
    return False

然而,像这样直接返回结果会更简洁:

def function():
    return isinstance(a, b) or issubclass(b, a)

只有当表达式的计算结果为布尔值时才能执行此操作。在这个例子中:

def any_hats():
    hats = [item for item in wardrobe if is_hat(item)]
    if hats or self.wearing_hat():
        return True
    return False

我们不能进行这种精确的重构,因为现在我们可以返回hats的列表,而不是True或False。为了确保返回的是一个布尔值,可以调用bool()来包装返回值:

def any_hats():
    hats = [item for item in wardrobe if is_hat(item)]
    return bool(hats or self.wearing_hat())
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值