我们已经准备好了,你呢?

2024我们与您携手共赢,为您的企业形象保驾护航!

什么是“工匠”?

我一直觉得编程在某种意义上是一门“手艺”,因为优雅高效的代码就像完美的手工艺品一样赏心悦目。在雕刻代码的过程中,有很大的项目:比如应该使用什么架构和设计模式。还有更多的小细节,比如何时使用(),或者如何命名变量。那些真正优秀的代码是由无数优秀的细节创造出来的。 《工匠》这个系列文章是我的一个小小的尝试。重点分享编程中的一些“小”事。希望能够对编程路上的每一位工匠有所帮助。

系列文章:

关联:

关联:

前言

编写条件分支代码是编码过程的一个组成部分。如果我们用道路来比喻,现实世界中的代码从来都不是一条笔直的高速公路,而更像是由无数岔路组成的城市地图。我们程序员就像司机一样,我们需要告诉程序在下一个路口是否需要向左走还是向右走。编写良好的条件分支代码很重要,因为糟糕、复杂的分支处理很容易让人们感到困惑并降低代码质量。因此,本文将重点讨论在 .

分支代码在

它支持最常见的 if/else 条件分支语句,但缺少其他编程语言中常见的 /case 语句。此外,还为for/while循环和try/语句提供了else分支,这在一些特殊场景下很有用。下面我将从最佳实践、常用技巧、常见陷阱三个方面来谈谈如何编写优秀的条件分支代码。

最佳实践 1. 避免多级分支嵌套

如果这篇文章只能精简为一句话,那么那句话一定是“尽力避免分支嵌套”。分支嵌套太深是许多新手程序员最常犯的错误之一。如果新手程序员写了很多层分支嵌套,你可能会看到一层又一层的花括号:if { if { if { ... }}}。俗称“嵌套如果地狱(If Hell)”。但是,由于使用缩进而不是 {},因此分支嵌套太深会比其他语言产生更严重的后果。例如,太多的缩进级别很容易导致代码超出 PEP8 中指定的每行字数限制。我们看一下这段代码:

def(书呆子,商店):

》》》去水果店买苹果

- 首先检查商店是否营业

- 如果有苹果,就买一个

- 如果你没有足够的钱,就回家拿点钱然后再回来

”“”

.():

。(“苹果”):

.(store.price("苹果",=1)):

nerd.buy(商店,"苹果",=1)

别的:

书呆子.y()

(书呆子,商店)

别的:

提高(“商店里没有苹果!”)

别的:

提高(“商店是!”)

上面代码最大的问题在于,它对原始条件分支需求的翻译过于直接,导致短短十几行代码就出现了三层嵌套分支。这样的代码可读性和可维护性都很差。然而,我们可以使用一个非常简单的技巧:“提前结束”来优化这段代码:

def(书呆子,商店):

.():

提高(“商店是!”)

。(“苹果”):

提高(“商店里没有苹果!”)

.(store.price("苹果",=1)):

nerd.buy(商店,"苹果",=1)

别的:

书呆子.y()

(书呆子,商店)

“提前终止”是指:在函数内使用raise或raise等语句提前结束分支中的函数。例如,在new函数中,当不满足分支条件时,我们直接抛出异常并结束代码分支。这样的代码没有嵌套分支,更直接、更容易阅读。

2.封装那些过于复杂的逻辑判断

如果条件分支中的表达式太复杂,有太多的not/and/or,那么这段代码的可读性就会大大降低,比如下面的代码:

# 如果活动仍在进行且活动剩余名额大于10,则所有性别均为女性,或者等级大于3

#活跃用户将获得10,000金币

。 。 > 10 和\

用户。 and(user.sex == ''.level > 3):

用户。(10000)

对于这样的代码,我们可以考虑将具体的分支逻辑封装成函数或者方法来简化代码:

.().tion():

用户。(10000)

事实上,重写代码后,原来的注释文字其实是可以去掉的。因为下面的代码已经达到了自解释的目的。至于具体哪些用户符合活动条件?这类问题应该通过具体的()方法来回答。

提示:适当的封装不仅直接提高了代码的可读性,事实上,如果上述活动判断逻辑在代码中出现不止一次,封装就更有必要了。否则,重复代码会极大地损害这个逻辑的可维护性。

3.注意不同分支下的重复代码

重复代码是代码质量的天敌,条件分支语句很容易成为重复代码的重灾区。因此,我们在编写条件分支语句时,需要特别注意,不要产生不必要的重复代码。让我们看一下这个例子:

# 对于新用户,创建新的用户配置文件,否则更新旧的配置文件

.:

=用户.,

电子邮件=用户.电子邮件,

年龄=用户.年龄,

=用户.,

# 对于新用户,将用户积分设置为0

=0,

=现在(),

别的:

=用户.,

电子邮件=用户.电子邮件,

年龄=用户.年龄,

=用户.,

=现在(),

在上面的代码中,我们一眼就可以看出,在不同的分支下,程序调用了不同的函数,做了不同的事情。但由于重复代码的存在,我们很难简单地区分两者的区别。事实上,得益于 的动态特性,我们可以简单地重写上面的代码,这样可读性就可以得到明显的提升:

.:

=

= {'': 0,'': 现在()}

别的:

=

= {'': 现在()}

=用户.,

电子邮件=用户.电子邮件,

年龄=用户.年龄,

=用户.,

**

当您编写分支代码时,请特别注意分支创建的重复代码块。如果你能简单地消除它们,请不要犹豫。

4.谨慎使用三元表达式

三元表达式语法仅在 2.5 版本之后支持。在此之前,社区一度认为三元表达式是不必要的,我们需要使用 x 和 a 或 b 来模拟它。 [注意]事实是,在很多情况下,使用普通的 if/else 语句确实使代码更具可读性。盲目追求三元表达式很容易诱惑你编写复杂、可读性差的代码。因此,请记住仅对简单逻辑分支使用三元表达式。

= "" if you.favor("") else ""

对于大多数情况,使用普通的 if/else 语句。

常见技巧1.使用“德摩根定律”

在进行分支判断时,我们有时会写这样的代码:

# 如果用户未登录或者用户没有使用,则拒绝提供服务

。 .:

“我们的仅供用户使用”

当你第一次看到代码的时候,是不是需要思考一会儿才能明白它想要做什么?这是因为上面的逻辑表达式中有2个not和1个or。而我们人类恰好不善于处理太多的“否定”和“或”逻辑关系。这个时候,德摩根定律就该出场了。通俗地说,德摩根定律就是not A或not B等价于not(A和B)。通过这样的转换,上面的代码可以改写如下:

如果不是(用户..):

“我们的服务仅对用户开放”

怎么样?代码是不是更容易阅读了?请记住德摩根定律,该定律对于简化条件分支中的代码逻辑通常非常有用。

2. 自定义对象的“布尔真假”

我们常说,在互联网中,“万物皆对象”。事实上,不仅仅是“一切皆对象”,我们还可以使用很多神奇的方法(文档中称为:user-)来定制对象的各种行为。我们可以通过许多神奇的方式影响代码的执行,而这在其他语言中是不可能做到的。例如,所有对象都有自己的“布尔真或假”:

通过内置函数 bool(),您可以轻松检查对象的布尔值 true 或 false。在进行条件分支判断时也会使用该值:

>>> 布尔(())

真的

重要的是,尽管所有用户类实例的布尔值都是 true。但有一种方法可以改变这种行为:自定义类的魔术方法(2.X 版本中)。当类定义方法时,其返回值将被视为类实例的布尔值。此外,布尔值并不是影响实例真假的唯一方法。如果类没有定义方法,它也会尝试调用该方法(即对任意序列对象调用len函数),通过结果是否为0来判断实例是true还是false。那么什么是这个功能的使用?看一下下面的代码:

():

def(自身,用户):

自己。 = 用户

用户 = ([,])

iflen(用户。) > 0:

print("有一些用户在!")

上面的代码中,users的长度。用于判断是否有内容。事实上,上面的分支可以通过添加魔术方法来变得更简单:

:

def(自身,用户):

自己。 = 用户

定义(自我):

(自己。)

用户 = ([,])

# 定义方法后,可以利用对象本身进行布尔判断

:

print("有一些用户在!")

通过定义魔术方法 and ,我们可以让类控制我们想要表达的布尔 true 和 false 值,使代码更加简洁。

3.条件判断中使用all()/any()

all()和any()这两个函数非常适合用在条件判断中。这两个函数接受一个可迭代对象并返回一个布尔值,其中:

假设我们有以下代码:

定义():

"""仅当序列中的所有数字都大于 10 时才返回 True

”“”

:

:

干扰素)

简单高效且不牺牲可用性。

4.在try/while/for中使用else分支

我们来看看这个函数:

定义():

d = 假

尝试:

()

d=真

酶:

print("错误时")

# 只有成功完成才做第二件事

sed:

事物()

在函数中,我们希望只有()调用成功(即不抛出异常),才能继续进行第二次函数调用。为此,我们需要定义一个附加变量 d 作为标记。其实我们可以用更简单的方法来达到同样的效果:

定义():

尝试:

()

酶:

print("错误时")

别的:

事物()

else分支追加到try语句块的末尾后,只有当try下的所有语句都正常执行后(即不存在异常、no、break等)后,才会执行该分支下的() 。同样,for/while循环中也支持添加else分支,这意味着只有当循环使用的迭代对象正常耗尽,或者while循环使用的条件变量变为False时,才会执行else分支下的代码。

常见陷阱 1. 与 None 值比较

在 中,有两种比较变量的方式: == 和 is,它们在含义上有根本的区别:

None 是语言中的单例对象。如果要判断一个变量是否为None,记得使用is而不是==,因为只有is才能表达严格意义上的变量是否为None。否则,可能会出现以下情况:

>>> ():

... def(自己,其他):

...

...

>>> foo = Foo()

>>> foo == 无

真的

上面的代码中,Foo类通过自定义magic方法,轻松满足条件== None。所以,当你想判断一个变量是否为None时,使用is而不是==。

2、注意and和or的运算优先级

看下面两个表达式。猜猜它们是否具有相同的值?

>>> ()

>>>

答案是:不是,它们的值分别是False和True。你猜对了吗?问题的关键是:and运算符的优先级大于or。所以上面的第二个表达式实际上看起来是 True 或 (False and False)。所以结果是 True 而不是 False。在编写包含多个and 和or 的表达式时,请特别注意and 和or 的运算优先级。即使执行优先级正是您所需要的,您也可以添加额外的括号以使代码更清晰。

结论

以上是“工匠”系列文章的第二篇。不知道文章的内容是否合你的胃口。代码中的分支语句是不可避免的。我们在写代码的时候,需要特别注意它的可读性,避免给其他看到代码的人带来麻烦。看完文章,你有什么想吐槽的吗?请留言告诉我。

注解

事实上,x 和 a 或 b 并不总是给出正确的结果。这个表达式只有当a和b的布尔值为true时才能正常工作。这是由逻辑运算的短路特性决定的。您可以在命令行上尝试 True 和 None 或 0,结果将是 0 而不是 None。

二维码
扫一扫在手机端查看

本文链接:https://by928.com/7324.html     转载请注明出处和本文链接!请遵守 《网站协议》
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。

项目经理在线

我们已经准备好了,你呢?

2020我们与您携手共赢,为您的企业形象保驾护航!

在线客服
联系方式

热线电话

13761152229

上班时间

周一到周五

公司电话

二维码
微信
线