Python基础语法:流程控制语句(if、match、for else、while else、try、is、in、not、with、lambda)
三位运算符 if else
Java中的三位运算符是用 StringUtils.isNotEmpty(nickname) ? nickname : "" 来实现的。Python中是用x if cond else y来实现的(突然换种语法感觉不太适应)
// Java
int a = 2;
int b = 1;
int result = a >= b ? a : b;
# Python
a = 2
b = 1
# if条件成立返回if前面的表达式,if条件不成立返回else对应的表达式
result = a if a >= b else b
Python 不用 ?:,而用 x if cond else y,是一个有意的语言设计选择,核心是让代码按自然语序读起来更清楚,降低嵌套时的可读性灾难。Python 确实在“短”与“可读”之间,经常优先后者。
为什么不用 ? : 主要有几个原因:
- Python 语法哲学偏“可读性优先”: ?: 很短,但对很多人(尤其新手)不直观。a if cond else b 基本就是英文句子:“如果 cond,就 a,否则 b”。
- 避免 C/Java 风格三元在复杂表达式里的“符号噪音”,像这种在 ?: 里嵌套时很容易变难读:a ? b : c ? d : e, Python 版本虽然也可能复杂,但关键词更显眼: b if a else d if c else e
- 和 Python 的关键字风格一致:Python 很多控制结构都偏好关键字而不是符号:and/or/not、is、in。if … else … 延续了这种风格。
- 历史上确实讨论过:Python 社区当年为“条件表达式”讨论了很久,最后选择了现在这个写法,而不是 ?:。不是没想到 ?:,而是权衡后主动没选。
适用场景:
- 建议只在简单场景用:status = “adult” if age >= 18 else “minor”
- 如果分支逻辑一复杂,就改普通 if/else,这也符合 Python 风格。
or 布尔逻辑运算符
如果 or 前面的布尔表达式为True取当前表达式的值,如果为False取or后面的表达式的值,常用来判断值为空(值为空则为False)给一个默认值。 or 是三元运算符的一种情况下的简写。
flag = False
# 默认值1
print(flag or "默认值1")
# 默认值2
print([] or "默认值2")
# 默认值3
print("" or "默认值3")
# openai
print("openai" or "默认值4")
x = 5
result = "大于0" if x > 0 else "小于等于0"
flag = True
res1 = "是" if flag else "否"
res2 = flag or "否" # 如果 flag 是 False,返回 "否"
# 返回第一个为 True 的值,否则返回最后一个值
a = 0
b = ""
c = "hello"
result = a or b or c
print(result) # 输出:"hello"
- if else:支持任意场景,条件为真时可以返回任意值
- or : 一般直接判断某个变量的值是否True,为真则直接返回当前值,不为真则返回后面的值,而if else 为真时是可以返回任意表达式的。or还支持连续使用。
取反not
一般其它开发语言中取反操作使用感叹号!,而Python对bool值取反使用not关键字, 有点类似于SQL语法。
flag = False
# True
print(not flag)
print(1 in [1, 2, 3])
print(4 not in [1, 2, 3])
Python 选择 not 而不是 !,not 的选择确实体现了 Python 一贯的取舍,不是追求最短输入,而是追求“更容易读对”。
通常有这几层考虑:
- 可读性: if not ready: 对英文阅读更自然,接近自然语言。相比 if !ready,关键字更“语义化”。
- 语法一致性:Python 逻辑运算整体是单词体系:and / or / not。不用 && / || / !,风格统一,学习成本更平滑。
- 降低符号密度:符号多时,表达式容易“眼花”,尤其对初学者和跨语言读者。 Python 倾向把控制与逻辑写得更像“句子”。
- 避免与其他符号组合造成视觉负担: 像 != 这种比较符号仍保留(因为非常通用),但一元逻辑取反用单词能减少连串符号阅读负担。
关键字 is(内存地址)
is 用来判断两个变量是否指向同一个对象(同一内存身份),不是判断值是否相等。
is:比较对象身份内存地址(identity)==:比较对象值(equality)
Java中判断内存地址是使用 ==,判断值是否相等使用equals()
Foobar a = new Foobar("a");
Foobar b = new Foobar("b");
System.out.print(a == b)
if (a == null) {
System.out.print("a is null")
}
Python中使用is关键字判断是否为同一个内存地址,使用 == 判断值是否相等,在==符号上Python和Java的意义完全不一样。
a = [1, 2]
b = [1, 2]
c = a
print(a == b) # True,值相同
print(a is b) # False,不是同一个对象
print(a is c) # True,c 和 a 指向同一个对象
# Python
foobar = None
if foobar is None:
print('foobar = None')
# 常见正确用法是和 None 比较,不建议用 is 比较数字、字符串等“值”,因为可能受实现细节影响,语义也不对。
if x is None:
...
if x is not None:
...
match case 模式匹配
Java中使用 switch case 预发,要匹配多个值需要写多次case只是不写对应的代码块即可。
int day = 3;
switch (day) {
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println("工作日");
break;
case 6:
case 7:
if (day == 6) {
System.out.println("周六");
} else if (day == 7) {
System.out.println("周末");
}
break;
default:
System.out.println("无效日期");
break;
}
Python中使用match关键字,case 一次匹配多个值时使用 |,不用像Java那样还要在另起一行(这点语法更简洁)满足case值时还可以使用 if 守卫条件,满足if条件才能进入case,Java还要在case里面判断,对于简单的条件判断Python的这种方式更加简洁,而且不需要break关键字。
match 表达式:
case 值1:
操作1
case 值2 if 条件表达式:
操作2
case 值3 | 值4:
操作4
case:
默认操作
Python 想解决的不是传统 switch 那个问题,而是更强的“结构化匹配”问题,所以直接引入了 match, 这比 switch 强很多,语义也不同,命名上刻意区分, Python 这个特性本质上是“pattern matching”,叫 match 更准确,避免误解。
- 传统 switch 能力太窄:很多语言的 switch 主要是“一个值和一组常量比较”。Python 社区长期觉得这种能力用 if/elif 已经够了,没必要单独加关键字。
- Python 需要的是模式匹配,不只是值匹配:match 可以按“数据形状”匹配并解构,比如:
- 元组/列表结构
- 字典键结构
- 类对象字段
- 还可以加守卫条件(if)
from dataclasses import dataclass
# 类对象模式匹配示例用的数据类
@dataclass
class Point:
x: int
y: int
def demo_match(value):
match value:
# 1) case 单值(字面量)
case 0:
return "单值: zero"
# 2) case 多值(| 或模式)
case 1 | 2 | 3:
return "多值: one/two/three"
# 3) case 解构:列表
case [x, y]:
return f"列表解构: 两个元素 x={x}, y={y}"
case [first, *rest]:
return f"列表解构: first={first}, rest={rest}"
# 4) case 解构:字典
case {"type": "login", "user": user}:
return f"字典解构: login user={user}"
# **rest 捕获未显式匹配到的其余键
case {"type": "pay", "amount": amount, **rest}:
return f"字典解构: pay amount={amount}, rest={rest}"
# 5) case 解构:类对象
# 按属性名匹配
case Point(x=0, y=0):
return "类对象解构: 原点"
# 按位置匹配(dataclass 默认支持 __match_args__)
case Point(x, y):
return f"类对象解构: Point({x}, {y})"
# 6) case 守卫条件(if)
case int(n) if n > 100:
return f"守卫条件: 大整数 {n}"
case str(s) if s.strip() == "":
return "守卫条件: 空白字符串"
# 兜底
case _:
return f"未匹配: {value!r}"
if __name__ == "__main__":
samples = [
0, # 单值
2, # 多值
[10, 20], # 列表解构(定长)
[1, 2, 3, 4], # 列表解构(*rest)
{"type": "login", "user": "alice"}, # 字典解构
{"type": "pay", "amount": 99, "currency": "CNY"}, # 字典解构 + **rest
Point(0, 0), # 类对象解构(命名)
Point(3, 4), # 类对象解构(位置)
150, # 守卫条件
" ", # 守卫条件
("x", "y"), # 未匹配
]
for item in samples:
print(f"{item!r} -> {demo_match(item)}")
while else 和 for else
循环代码块中可以有else代码块(我也是第一次见到这种语法),当循环条件为False时执行else。
else表示正常结束循环体才会执行,如果循环体中遇到break时不执行else代码块的。
for/while … else 主要用于“有 break 的循环”,表达“未触发 break 的兜底分支”。没有 break 的循环里,一般没必要写 else。
nums = [1, 3, 5, 8]
target = 7
for n in nums:
if n == target:
print("找到了")
break
else:
print("没找到")
假设尝试连接一个服务最多 3 次,如果某次成功就 break,否则执行 else 中的失败处理的兜底逻辑
attempts = 0
max_attempts = 3
while attempts < max_attempts:
if connect_to_service(): # 假设返回 True 表示连接成功
print("连接成功")
break
attempts += 1
else:
print(f"重试 {max_attempts} 次后仍然失败")
不用 else 也能写,但通常要加一个标志位,这样就多了2行代码(一行是声明标志变量,一行是标志位是否为为True),这也是Python精简代码的提现。
found = False
for n in nums:
if n == target:
found = True
break
if not found:
print("没找到")
适合:
- 明确的“找到了就提前结束,否则执行
兜底”的逻辑 - 不想额外引入 found = False 这类标记变量时
作用:在循环未遭遇 break 的情况下执行收尾代码。
使用场景:任何需要根据“循环是否提前结束”来做不同处理的场合,尤其是查找、校验、重试等逻辑。
异常 try except else finally
在其它编程语言中一般都是try catch finally, Python用的不是catch而是except,并且python还支持else代码块。else子句将在try子句没有发生任何异常的时候执行。注意代码块的顺序:try → except | else → finally。捕获后还可以通过 raise 再次抛出异常,再次抛出时可以直接抛出 raise,也可以带上当前异常信息 raise e。
# try → else → finally
try:
print('try')
except Exception as e:
print('except')
else:
print('else')
finally:
print('finally')
try:
print('try')
except Exception as e:
print('except')
raise
else:
print('else')
finally:
print('finally')
# try → except → finally
try:
print('try')
1/0
except Exception as e:
print('except')
else:
print('else')
finally:
print('finally')
# try → else → finally
try:
print('try')
except Exception as e:
print('except')
else:
print('else')
# 注意:else出现异常不会走except
print(1/0)
finally:
print('finally')
else 子句的作用是:仅当 try 块中没有抛出任何异常时,才会执行 else 块中的代码,如果 try 块中发生了异常并被某个 except 捕获,else 块会被跳过,也就是是说 except和else是互斥分支。这就意味着else中的代码发生异常时不会走except。
else:只在无异常时执行,常用于放置依赖于 try 块成功执行后的代码; finally:无论是否发生异常,都会在最后执行(一般用于资源释放)。
常用场景:依赖 try 操作结果的后续正常处理;控制 try 范围使其只包含真正预期会抛异常的代码。
# 这个示例功能是等价的
try:
x = int(input("请输入数字"))
except ValueError:
print("输入不是数字")
else:
print("转换成功", x) # 只在 try 成功时执行
---
try:
x = int(input("请输入数字"))
print("转换成功", x)
except ValueError:
print("输入不是数字")
else 的价值主要不是“功能新增”,而是异常边界更精确:
- 放在 try 里:except ValueError 会处理 try 内所有可能的 ValueError
- 放在 else 里:except ValueError 只处理“主操作”(这里是 int(…))的 ValueError
# 不用 else:容易误捕获
try:
x = int(input("请输入数字: "))
y = int(input("再输入一个数字: ")) # 这里也可能 ValueError
except ValueError:
print("第一个输入不是数字") # 这个提示可能是错的
# 用 else:边界清楚
try:
x = int(input("请输入数字: "))
except ValueError:
print("第一个输入不是数字")
else:
y = int(input("再输入一个数字: ")) # 这里出错就不是上面那个 except 的责任
在真实代码里,else 能避免“误捕获”,让异常处理更准确、可维护性更好。
with关键字
with关键字的作用自动关闭资源或者自动获取锁和自动释放锁,不需要显式的关闭资源和释放锁,相当于Java中的try() catch 语法。
// 使用 try-with-resources 自动关闭 BufferedReader 和 FileReader
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
# 手动关闭资源
try:
f = open("test.txt")
print(f.readline())
except BaseException as e:
print(e)
finally:
f.close()
# with自动方式
with open('example.txt', 'r', encoding='utf-8') as file:
for line in file:
# 每次循环读取一行,包含末尾的换行符 '\n'
print(line, end='') # end='' 避免重复换行
with自动获取锁和释放锁
import threading
lock = threading.Lock()
lock.acquire()
print("线程安全代码...")
lock.release()
import threading
lock = threading.Lock()
with lock:
print("线程安全代码...")
代码块全局变量
在代码块(if、try、while、for)中声明的变量是全局变量
Python在代码块中声明的变量是"全局变量",这和Java语言完全相反,Java在代码块中声明的变量都是局部变量,这就意味着Python在下面可以访问任意代码块中定义的变量,这样一来代码就少了一行,这也是python精简的一个体现。
// Java中要想方法代码块中的变量只能将代码块中的变量提取出来
boolean flag = false;
if (true) {
flag = true;
}
System.out.print(flag)
if True:
a = "this is global variable"
print(a)
try:
b = "try"
except ValueError:
# 局部变量,外面不能访问
c = "except"
else:
d = "else"
finally:
e = "finally"
print(b)
# print(c)
print(d)
print(e)
while True:
f = "while"
break
print(f)
for i in range(10):
g = "for"
print(g)
lambda表达式
lambda表达式在很多编程语言中都有类似语法。lambda表达式就是一个有参数有返回值的匿名函数。
- Python中的lambda表达式必须使用
lambda关键字声明 - Python中的lambda式的方法体只能是一行代码,不能是代码块,Java中支持代码块多行语句。
// Java多行语句
Runnable task = () -> {
for (int i = 1; i <= 5; i++) {
System.out.println("计数: " + i);
}
System.out.println("任务完成");
};
# Python只允许一行代码
sum = lambda x, y: x + y
print(sum(1, 2))
# <class 'function'>
print(type(sum))
更多推荐



所有评论(0)