乐趣区

关于python:冗长的-Python-代码如何重构

【导语】:对本人写的简短代码,想重构但又无思路?小编整顿了系列介绍 python 代码重构优化的办法,助你一臂之力。

编写洁净的 Pythonic 代码就是尽可能使其易于了解,但又简洁。

这是 Python 重构系列中的之一,本系列文章的重点是为什么这些重构是好主见,而不仅仅是如何做。

1. 将 for 循环转换为 list/dictionary/set 表达式

咱们在时常常遇到的一个状况是,创立一个值的汇合。

比方咱们创立一个列表,而后迭代地用值填充它,这里咱们想创立一个立方数字的列表。大多数语言的规范办法如下:

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

在 Python 中,咱们能够应用列表表达式,生成须要的数据。就能够将代码简化为一行,省去定义列表,而后再去填充列表的略显繁琐的操作。

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

看,咱们曾经将三行代码转换成一行,这无疑是不错的抉择——你的眼睛不必上下左右的查看代码。

把代码压缩到一行会使浏览变得更加艰难,但对于推导表达式来说,状况并非如此。您须要的所有元素都被很好地出现进去,一旦您习惯了语法,它实际上比 for 循环版本更具可读性。

另一点是赋值当初更像是一个原子操作——咱们申明什么是 cubes,而不是给出如何构建它的指令。这使得代码读起来更舒服,因为咱们关怀变量 cubes 是什么,而不是它的结构细节。

最初,表达式通常比在循环中构建汇合更快,如果思考性能,这也是重要因素。

2. 用增量赋值替换赋值

增量赋值是一种疾速而简略的 Python 语法。

只有有这样的代码:

count = count + other_value

都能够替换成上面的代码:

count += other_value

代码是简短和清晰的 - 咱们不须要思考计数变量两次。其余能够应用的运算符包含 -=,=,/= 和 *=。

不过有件事须要略微小心一点,你要调配给的类型必须定义适当的运算符。例如,numpy 数组不反对 /= 操作。

3. 只应用一次的内联变量

咱们在人们的代码中常常看到的一种状况是将后果赋给长期变量,而后立刻返回它。

def state_attributes(self):
    """Return the state attributes."""
    state_attr = {
        ATTR_CODE_FORMAT: self.code_format,
        ATTR_CHANGED_BY: self.changed_by,
    }
    return state_attr

其实更好的办法是间接返回后果,而不是再用一个长期变量寄存后果

def state_attributes(self):
    """Return the state attributes."""
    return {
        ATTR_CODE_FORMAT: self.code_format,
        ATTR_CHANGED_BY: self.changed_by,
    }

这样能够缩短代码并删除不必要的变量,从而缩小浏览代码的脑力耗费。

长期变量可能有用的中央是,如果它们被用作参数或条件,并且名称能够代表内容。在下面的例子中,返回的是 state 属性,并且 state_attr 没有提供任何额定的信息。因而不用将后果赋给长期变量。

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

常常会遇到的一种状况是,您常常心愿将一个变量设置为两个不同值中的一个。

if condition:
    x = 1
else:
    x = 2

这能够应用 Python 的条件表达式语法(python 的三元运算符版本)在一行上编写:

x = 1 if condition else 2

这必定更简洁,但它是一个更有争议的重构(就像列表表达式)。一些程序员不喜爱这样的表达式,因为感觉它们比齐全写出 if 条件更难解析。

咱们的观点是,只有条件表达式很短并且适宜合并,那就是一种改良,晋升效率。与列表表达式的示例相似,当咱们浏览代码时,通常不须要晓得 x 是如何调配的,只需看到它被赋值,而后持续向前。

5. 用生成器代替不须要的表达式

一个技巧是像 any、all 和 sum 这样的函数容许传入 generator 而不是 collection。这意味着,与其这样做:

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

能够将代码改成:

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

这将删除一对括号,使代码略微清晰一些。如果 any 函数找到后果,会立刻返回,而不用构建整个列表。这能够导致性能晋升。

请留神,咱们实际上是将生成器传递到 any()中,严格地说,代码应该如下所示:

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

然而 Python 容许您省略这对括号。上面是承受 generator 的规范库函数:

'all', 'any', 'enumerate', 'frozenset', 'list', 'max', 'min', 'set', 'sum', 'tuple'

6. 将条件简化为 return 语句

最初介绍的重构技巧是,函数须要返回后果是 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

这个示例,能够通过 bool() 将 hat 和 self.wearing_hat() 合成 bool 列表,就能够打消 if 条件,达到简化程序的目标。

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

以上就是本次分享的所有内容,想要理解更多 python 常识欢送返回公众号:Python 编程学习圈 ,发送“J”即可收费获取,每日干货分享

退出移动版