条件语句和清晰代码风格

发布时间 2023-11-28 20:05:52作者: Shun了个shun

if语句

def f(x):
  print("A", end="")
  if x == 0:
      print("B", end="")
      print("C", end="")
  print("D")
f(1)
AD

//

def abs1(n):
  if n < 0:
      n = -n
  return n

写在一行

def abs2(n):
  if n < 0: n = -n
  return n

除非有特殊原因,否则强烈建议不要这样写

多个返回语句

def abs4(n):
  return (n < 0)*(-n) + (n>=0)*(n) # 这家伙长得太奇怪了

最好不要这样写

验证结果正确性

print("abs1(5) =", abs1(5), "and abs1(-5) =", abs1(-5))
print("abs2(5) =", abs2(5), "and abs2(-5) =", abs2(-5))
print("abs3(5) =", abs3(5), "and abs3(-5) =", abs3(-5))
print("abs4(5) =", abs4(5), "and abs4(-5) =", abs4(-5))
abs1(5) = 5 and abs1(-5) = 5
abs2(5) = 5 and abs2(-5) = 5
abs3(5) = 5 and abs3(-5) = 5
abs4(5) = 5 and abs4(-5) = 5

if-else 语句 if-else statement

x = input("x=")
x = float(x)
print("hello")
if x < 10:
  print("wahoo!")
print("goodbye")
x=9
hello
wahoo!
goodbye

if-elif-else 语句

ef f(x):
  print("A", end="")
  if x == 0:
      print("B", end="")
      print("C", end="")
  elif x == 1:
      print("D", end="")
  else:
      print("E", end="")
      if x == 2:
          print("F", end="")
      else:
          print("G", end="")
  print("H")

if-else 推导式 if-else expression

def abs7(n):
  return n if (n >= 0) else -n
print("abs7(5) =", abs7(5), "and abs7(-5) =", abs7(-5))
abs7(5) = 5 and abs7(-5) = 5

这个函数的作用是计算一个数的绝对值。在Python中,可以使用条件表达式(也称为三元运算符)来实现这个功能。条件表达式的语法是:

value_if_true if condition else value_if_false

在这个例子中,value_if_truen本身,conditionn >= 0value_if_false-n。当n >= 0成立时,条件表达式的值为n;否则,条件表达式的值为-n

//

match-case 语句

简单解释

match subject: case <pattern_1>: <action_1> case <pattern_2>: <action_2> case <pattern_3>: <action_3> case _: <action_wildcard>

简单模式:匹配一个字面值

让我们把这个例子看作是模式匹配的最简单形式:一个值,即主词,被匹配到几个字面值,即模式。在下面的例子中,status 是匹配语句的主词。模式是每个 case 语句,字面值代表请求状态代码。匹配后,将执行与该 case 相关的动作:

def http_error(status): match status: case 400: return "Bad request" case 404: return "Not found" case 418: return "I'm a teapot" case _: return "Something's wrong with the internet"如果传给上述函数的 status 为 418,则会返回 "I'm a teapot"。 如果传给上述函数的 status 为 500,则带有 _ 的 case 语句将作为通配符匹配,并会返回 "Something's wrong with the internet"。 请注意最后一个代码块:变量名 _ 将作为 通配符 并确保目标将总是被匹配。 _ 的使用是可选的。

你可以使用 | (“ or ”)在一个模式中组合几个字面值:

case 401 | 403 | 404: return "Not allowed"

无通配符的行为

如果我们修改上面的例子,去掉最后一个 case 块,这个例子就变成:

def http_error(status): match status: case 400: return "Bad request" case 404: return "Not found" case 418: return "I'm a teapot" 如果不在 case 语句中使用 _,可能会出现不存在匹配的情况。如果不存在匹配,则行为是一个 no-op。例如,如果传入了值为 500 的 status ,就会发生 no-op。

带有字面值和变量的模式

模式可以看起来像解包形式,而且模式可以用来绑定变量。在这个例子中,一个数据点可以被解包为它的 x 坐标和 y 坐标:

point is an (x, y) tuple

match point: case (0, 0): print("Origin") case (0, y): print(f"Y={y}") case (x, 0): print(f"X={x}") case (x, y): print(f"X={x}, Y={y}") case _: raise ValueError("Not a point") 第一个模式有两个字面值 (0, 0) ,可以看作是上面所示字面值模式的扩展。接下来的两个模式结合了一个字面值和一个变量,而变量 绑定 了一个来自主词的值(point)。 第四种模式捕获了两个值,这使得它在概念上类似于解包赋值 (x, y) = point 带有字面值和变量的模式

模式可以看起来像解包形式,而且模式可以用来绑定变量。在这个例子中,一个数据点可以被解包为它的 x 坐标和 y 坐标:

point is an (x, y) tuple

match point: case (0, 0): print("Origin") case (0, y): print(f"Y={y}") case (x, 0): print(f"X={x}") case (x, y): print(f"X={x}, Y={y}") case _: raise ValueError("Not a point") 第一个模式有两个字面值 (0, 0) ,可以看作是上面所示字面值模式的扩展。接下来的两个模式结合了一个字面值和一个变量,而变量 绑定 了一个来自主词的值(point)。 第四种模式捕获了两个值,这使得它在概念上类似于解包赋值 (x, y) = point

更多内容见原文链接:https://blog.csdn.net/Datapad/article/details/123205558

清晰的代码风格 Clarity and style

请注意: 本节讨论的内容主要针对样式而非正确性,这里的所有例子都“正确的”,但有些例子比其他例子更巧妙,我们希望大家形成一个好的代码习惯。

否定条件(带有 else 部分)

# 可能不清晰的:
b = True
if not b:
  print('no')
else:
  print('yes')
yes
# 清晰的:
b = True
if b:
  print('yes')
else:
  print('no')
yes

空白的 if 部分

# 不清晰的:
b = False
if b:
  pass
else:
  print('no')
no
# 清晰的:
b = False
if not b:
  print('no')
no

用嵌套的 if 而不是 and 来判断

# 混乱的:
b1 = True
b2 = True
if b1:
  if b2:
      print('both!')
both!
# 清晰的:
b1 = True
b2 = True
if b1 and b2:
  print('both!')
both!

使用 if 而不是 else 来控制

# 可能会引入 bug:
b = True
if b:
  print('yes')
if not b:
  print('no')
yes
# 更好的做法:
b = True
if b:
  print('yes')
else:
  print('no')
yes

另外一个例子

# 又混乱又有产生 bug 的风险:
x = 10
if x < 5:
  print('small')
if (x >= 5) and (x < 10):
  print('medium')
if (x >= 10) and (x < 15):
  print('large')
if x >= 15:
  print('extra large')
large
# 更好的做法:
x = 10
if x < 5:
  print('small')
elif x < 10:
  print('medium')
elif x < 15:
  print('large')
else:
  print('extra large')
large

再来一个例子

# 又混乱又有产生 bug 的风险:
c = 'a'
if (c >= 'A') and (c <= 'Z'):
  print('Uppercase!')
if (c >= 'a') and (c <= 'z'):
  print('lowercase!')
if (c < 'A') or ((c > 'Z') and (c < 'a')) or (c > 'z'):
  print ('not a letter!')
lowercase!
# 更好的做法:
c = 'a'
if (c >= 'A') and (c <= 'Z'):
  print('Uppercase!')
elif (c >= 'a') and (c <= 'z'):
  print('lowercase!')
else:
  print('not a letter!')

使用一些 trick(如用算数逻辑来代替布尔逻辑)

# 不清晰的:
x = 42
y = ((x > 0) and 9)
# 清晰的:
x = 42
if x > 0:
  y = 99