2

从一段小代码开始学习如何重构

 2 years ago
source link: https://foofish.net/python-refactor.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

这篇文章告诉你如何将一个可读性很差的代码最后重构到只有一行代码的全过程,希望可以给你带来启发

这是一段来自网络上的代码, 代码能正常运行

def myfunc(a):
    empty = []
    for i in range(len(a)):
        if a[i].isupper() == True:
            empty.append(a[i].lower())
        else:
            empty.append(a[i].upper())
    return "".join(empty)

看函数名字你肯定不知道他是干什么的。

先来执行一下

print(myfunc("helloWORLD"))
print(myfunc("zenofpython"))
HELLOworld
ZENOFPYTHON

把代码全部读完后估计你可能已经猜出来这个函数的作用了,就是将字符串大小写互换,大写字母变小写,小写字母变大写。

如何提高代码的可读性同时让执行效率也能得到提升?

优化变量名

名字是最直接关系到代码可读性的,所以我们第一步从名字着手进行重构,一个见名知义的名字能让代码变得可读。

在这个例子中,除了函数名没有表达它改有的功能外,函数内部也充斥着很多没有意义的变量名, a, i ,empty 都是没有意义的名字。

def swapcase(text):
    letters = []
    for i in range(len(text)):
        if text[i].isupper() == True:
            letters.append(text[i].lower())
        else:
            letters.append(text[i].upper())
    return "".join(letters)

我在这里一共修改了3个地方的名字

  • myfunc -> swapcase, swapcase 就表示交换大小写,一看名字就知道函数的作用。
  • empty -> letters , empty 是个很空泛的名字,letters让看的人明白,这可能是个字母列表集合
  • a -> text , a 是啥,很迷惑,不去看上下文根本不知道, 用text表示,至少知道可能是个文本。

优化代码结构

第一个版本中,迭代字符串元素使用的还是传统的类C语言方式通过获取列表的下标索引来获取元素,这其实很不pythonic, 在 python中,for循环迭代时,每次拿到的其实就到里面的元素,没必要绕着弯子去获取元素。

def swapcase(text):
    letters = []
    for letter in text:
        if letter.isupper():
            letters.append(letter.lower())
        else:
            letters.append(letter.upper())
    return "".join(letters)

使用单行if else

另外,python中虽然没有三目运算符,但有个与之等价的 if else 语句放在一行代码中

def swapcase(text):
    letters = []
    for letter in text:
        new_letter = letter.lower() if letter.isupper() else letter.upper()
        letters.append(new_letter)
    return "".join(letters)

使用列表推导式

此外,列表推导式也是个好东西,用来替换不太复杂的for循环,能使代码更简洁

def swapcase(text):
    letters = [letter.lower() if letter.isupper() else letter.upper() for letter in text]
    return "".join(letters)

最后,你甚至可以将代码放在一行中完全所有任务

def swapcase(text):
    return "".join([letter.lower() if letter.isupper() else letter.upper() for letter in text])

使用类型注解

为了能让读代码的人减少理解成本,我们可以将类型定义以及注释加上

def swapcase(text: str) -> str:
    """
    将字符串大小写互换
    :param text: 原始字符串
    :return: 字符串
    """
    return "".join([letter.lower() if letter.isupper() else letter.upper() for letter in text])

这就是重构后的最后一个版本

终极大招,直接调用系统内置方法,其实python字符串已经内置了这样的函数,我们可以直接调用,而且它的性能更高,因为是用c实现的。 所以在我们写些代码前,先尝试找找是不是已经有轮子了。

"zenofpython".swapcase()

以上就是一个重构的小例子。 不积跬步无以至千里,不积小流无以成江海。 与大家共勉

有问题可以扫描二维码和我交流

关注公众号「Python之禅」,回复「1024」免费获取Python资源

python之禅

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK