如何提高代码可读性,再教你一招

如何提高代码可读性,再教你一招

Hello,各位小伙伴,在前面的几个章节中,我们重点讲解了Python的编程规范,其中对PEP8和Google编程规范进行了解读,其中对代码的缩进、行数、命名、注释等都有明确的规范,似乎我们按照这样的编程规范进行规范性写代码就可以了。

NO,我们还是要意识到一个关键性问题就是最早我问的那个问题,你的代码是写给谁的?很显然,肯定不仅仅是给机器去执行的,我们的代码很多的时候是为了给人看,那就需要做到让人能看懂和理解,所以才有了那些编程规范的要求,但是另一个问题是你在不同的团队或环境中写的代码是给不同的人阅读和理解的,那么此时遵守你们团队的编程规范才是王道,在符合团队或公司规范的情况下,去使用前面我们所讲解的编程规范才是正确的。

那是不是我按照团队或公司或官方指导的编程规范进行代码的编写就一定能够让人容易阅读了呢?

其实在大多数情况下已经可以了,因此编程规范非常重要,那么另外一个就是在这些基础上,让你的代码尽可能的简单、易读、逻辑清楚。那么除了遵守编程规范,还有什么办法来提高代码的可读性呢?

我的想法就是分解代码,很多情况下,我们的代码都是错中复杂,互相交织,这样即便按照一定的编程规范,也依然很难使你的代码变的具有可读性,因此本章节我们通过几个案例来看一下,如何通过合理分解代码来提高代码的可读性。

如何分解代码

首先,我们来看两个小代码段

# 第一段代码
if i_am_rich:
    money = 100
    send(money)
else:
    money = 10
    send(money)
    
# 第二段代码
if i_am_rich:
    money = 100
else:
    money = 10
send(money)

在上面的代码中,你可以看到两段代码的执行是一样的,但是第一段代码中,send调用出现了两次,因此我们把它修改变成第二段代码,我们把send合并了,而且达到了同样的效果。其实就是去除了重复代码,让代码更加易读。

作为一个程序员,那么肯定要知道编程中一个核心思想就是不写重复代码,重复代码基本都可以通过使用条件、循环、函数和类来解决。而另一个核心思想就是,减少迭代层数,尽可能让代码扁平化,让代码更加易读。我们经常在很多业务逻辑比较复杂的地方,使用大量的判断和循环。不过它可能会让你的代码失去阅读性。

再来看一个例子:

你能很好的阅读或理解这段代码吗?

def send(money):
    if is_server_dead:
        LOG('server dead')
        return
    else:
        if is_server_timed_out:
            LOG('server timed out')
            return
        else:
            result = get_result_from_server()
            if result == MONEY_IS_NOT_ENOUGH:
                LOG('you do not have enough money')
                return
            else:
                if result == TRANSACTION_SUCCEED:
                    LOG('OK')
                    return
                else:
                    LOG('something wrong')
                    return

如果我们改造一下:

def send(money):
    if is_server_dead:
        LOG('server dead')
        return

    if is_server_timed_out:
        LOG('server timed out')
        return

    result = get_result_from_server()

    if result == MONET_IS_NOT_ENOUGH:
        LOG('you do not have enough money')
        return

    if result == TRANSACTION_SUCCEED:
        LOG('OK')
        return

    LOG('something wrong')

这样会不会更加的清晰呢?

你看通过对代码结构的调整,代码一下就变得更加清晰,更具有易读性。所以,我们除了遵守编程规范以外就是要有更好的程序逻辑的表达能力。具备这样的能力才能写出具备可读性的代码。

如何分解函数

接下来我们再看一个关于函数的代码:

可以自己尝试写一下哦

下面是一个简单的二分查找函数,传递一个数组/列表 arr,和一个查找目标target。要求找到数组中最小的一个数x,可以满足x*x > target。如果不存在则返回-1

def solve(arr, target):
    l, r = 0, len(arr) - 1
    ret = -1
    while l <= r:
        m = (l + r) // 2
        if arr[m] * arr[m] > target:
            ret = m
            r = m - 1
        else:
            l = m + 1
    if ret == -1:
        return -1
    else:
        return arr[ret]


print(solve([1, 2, 3, 4, 5, 6], 8))
print(solve([1, 2, 3, 4, 5, 6], 9))
print(solve([1, 2, 3, 4, 5, 6], 0))
print(solve([1, 2, 3, 4, 5, 6], 40))

你看上面的代码,虽然已经实现了目标。可是在一个代码中写了判断、循环和运算,大多数人应该都会这样做,这样本身也没错。可是,我们应该让一个函数的颗粒度尽可能的细一些,不应该让一个函数处理太多的事情。所以,如果我们把这个复杂的函数进行分解,分成几个功能单一又简单的函数分别进行处理,那么应该怎么做呢?

函数分解:

我们把不同的处理代码进行了分离

  • Comp作为运算的核心,只做数据的计算
  • binary_search专门负责二分搜索
  • solve函数负责拿到结果来判断
def comp(x, target):
    return x * x > target

def binary_search(arr, target):
    l, r = 0, len(arr) - 1
    ret = -1
    while l <= r:
        m = (l + r) // 2
        if comp(arr[m], target):
            ret = m
            r = m - 1
        else:
            l = m + 1
    return ret

def solve(arr, target):
    id = binary_search(arr, target)

    if id != -1:
        return arr[id]
    return -1

print(solve([1, 2, 3, 4, 5, 6], 8))
print(solve([1, 2, 3, 4, 5, 6], 9))
print(solve([1, 2, 3, 4, 5, 6], 0))
print(solve([1, 2, 3, 4, 5, 6], 40))

你看,这样把一个复杂的函数分解成几个功能单一的函数,是不是就清晰了很多。

如何拆分类

最后,我们再来看一下如何拆分类。老规矩,先看代码:

class Person:
    def __init__(self, name, sex, age, job_title, job_description, company_name):
        self.name = name
        self.sex = sex
        self.age = age
        self.job_title = job_title
        self.job_description = description
        self.company_name = company_name

你应该能看得出来,job 在其中出现了很多次,而且它们表达的是一个意义实体,这种情况下,我们可以考虑将这部分分解出来,作为单独的类。

class Person:
    def __init__(self, name, sex, age, job_title, job_description, company_name):
        self.name = name
        self.sex = sex
        self.age = age
        self.job = Job(job_title, job_description, company_name)

class Job:
    def __init__(self, job_title, job_description, company_name):
        self.job_title = job_title
        self.job_description = description
        self.company_name = company_name

你看,改造后的代码,瞬间就清晰了很多。

总结

怎么样?通过上面的几个案例是不是感觉到了代码分解的重要性了呢?抓紧看看你写的代码吧,当然如果以前的可能没有很好的分解,我觉得不要因为这个原因去动,原因你知道的?

所以,希望大家通过本章的学习,能够在未来的coding中注意代码的可读性进行合理的代码分解。

如果喜欢本文或对你有帮助的话,欢迎大家关注我的公众号:后厂程序员,并分享、点赞、在看 三连哦。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351