本文系统梳理 Python 基础语法的核心知识点,涵盖变量类型、控制流、数据结构、函数、模块、面向对象编程等内容,适合初学者系统学习或开发者查漏补缺。
一、基本语法
1.1 变量与数据类型
Python 是动态类型语言,变量无需声明类型,解释器自动推断。
基本数据类型:
-
int--- 整数,无大小限制(Python 3) -
float--- 浮点数,双精度(64位),遵循 IEEE 754 -
complex--- 复数,如3+4j,可用.real/.imag访问实部虚部 -
str--- 字符串,不可变序列 -
bool--- 布尔值,True/False(首字母大写),是int的子类(True==1,False==0) -
NoneType--- 空值,None是唯一实例,表示"无"或"空"
类型转换与检查:
python
# 类型转换
int("123") # 123
float("3.14") # 3.14
str(100) # "100"
bool(1) # True
bool(0) # False
bool("") # False
# 类型检查
type(123) # <class 'int'>
isinstance(123, int) # True
isinstance(True, int) # True(bool 是 int 的子类)
1.2 运算符
运算符分类表:
| 类别 | 运算符 | 说明 |
|---|---|---|
| 算术 | + - * / // % ** |
加、减、乘、除、整除、取模、幂 |
| 比较 | == != > < >= <= |
比较值是否相等、大小 |
| 逻辑 | and or not |
逻辑与、或、非(短路求值) |
| 赋值 | = += -= *= /= //= %= **= |
赋值及复合赋值 |
| 成员 | in / not in |
检查元素是否在容器中 |
| 身份 | is / is not |
比较两个对象的内存地址是否相同 |
短路特性示例:
python
# and 短路:左侧为假时,右侧不执行
False and print("不会执行") # 什么都不打印
# or 短路:左侧为真时,右侧不执行
True or print("不会执行") # 什么都不打印
# 利用短路实现默认值
name = user_input or "匿名用户" # 如果 user_input 为空,使用默认值
== 与 is 的区别:
python
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True --- 值相等
print(a is b) # False --- 不是同一个对象(内存地址不同)
print(a is a) # True --- 同一个对象
# 实用场景:判断是否为 None
x = None
if x is None: # 推荐用 is,而非 ==
print("x 是 None")
小整数驻留(Interning)注意:
python
a = 256
b = 256
print(a is b) # True(CPython 缓存了 -5 到 256 的小整数)
a = 257
b = 257
print(a is b) # 可能是 False(不要在值比较时依赖 is)
1.3 运算符优先级(从高到低)
python
() → ** → +x, -x, ~x → *, /, //, % → +, - →
<<, >> → & → ^ → | → 比较运算 → not → and → or
口诀: 括号最高,幂次之,乘除模整除,加减,位移,位与,位异或,位或,比较,逻辑非,逻辑与,逻辑或,赋值最低。
python
# 实际开发中,加括号让意图更清晰,不必死记优先级
result = (a + b) * (c - d) / (e ** 2)
1.4 控制流
条件判断:if / elif / else
python
score = 85
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
elif score >= 60:
grade = "D"
else:
grade = "F"
print(f"等级:{grade}") # 等级:B
注意: Python 用缩进(推荐4个空格)表示代码块,不使用大括号。
for 循环
python
# 基本用法
for i in range(5):
print(i) # 0, 1, 2, 3, 4
# range 的三种形式
range(5) # 0, 1, 2, 3, 4
range(2, 5) # 2, 3, 4
range(0, 10, 2) # 0, 2, 4, 6, 8
range(10, 0, -1) # 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
# 遍历列表
fruits = ["苹果", "香蕉", "橙子"]
for fruit in fruits:
print(fruit)
# 遍历字典
person = {"name": "Alice", "age": 25, "city": "北京"}
for key in person: # 遍历键
print(key)
for value in person.values(): # 遍历值
print(value)
for key, value in person.items(): # 遍历键值对(最常用)
print(f"{key}: {value}")
可迭代对象: 字符串、列表、元组、字典、集合、
range()、文件对象等都可以被for遍历。
while 循环
python
count = 0
while count < 5:
print(f"计数:{count}")
count += 1
# 适合循环次数不确定的场景
while True:
user_input = input("输入 q 退出:")
if user_input == 'q':
break
break / continue / pass
python
# break:立即终止整个循环
for i in range(10):
if i == 5:
break
print(i) # 输出 0, 1, 2, 3, 4
# continue:跳过本轮剩余代码,进入下一轮
for i in range(10):
if i % 2 == 0:
continue
print(i) # 只输出奇数 1, 3, 5, 7, 9
# pass:占位符,什么都不做
def my_function(): # 还没想好怎么实现
pass
class MyClass: # 先占个位
pass
if condition: # 条件分支暂时不处理
pass
for...else 和 while...else
python
# 循环正常结束(未被 break 打断)时执行 else 块
for item in [1, 2, 3]:
if item == 10:
print("找到了")
break
else:
print("循环正常结束,没有找到 10")
# 实际应用:查找质数
def is_prime(n):
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
print(f"{n} 不是质数,能被 {i} 整除")
break
else:
print(f"{n} 是质数")
is_prime(17) # 17 是质数
is_prime(24) # 24 不是质数,能被 2 整除
1.5 输入与输出
print() 函数:
python
name = "Alice"
age = 25
# f-string(Python 3.6+,推荐)
print(f"我叫{name},明年{age + 1}岁")
# format() 方法
print("我叫{},明年{}岁".format(name, age + 1))
print("{0} 今年 {1} 岁".format(name, age)) # 按位置序号
# 自定义分隔符和结尾
print("A", "B", "C", sep=", ") # A, B, C
print("Hello", end=" ") # 不换行
print("World") # Hello World
# 格式化数字
pi = 3.1415926
print(f"圆周率:{pi:.2f}") # 圆周率:3.14
print(f"{12345678:,}") # 12,345,678(千分位)
print(f"{42:b}") # 101010(二进制)
input() 函数:
python
# input() 返回值始终是字符串类型
name = input("请输入你的名字:")
age = int(input("请输入你的年龄:")) # 需要数字时手动转换
height = float(input("请输入身高(米):"))
print(f"{name},{age}岁,身高{height}米")
二、核心内置数据结构
2.1 列表 list --- 可变有序序列
创建列表
python
# 多种创建方式
empty = [] # 空列表
nums = [1, 2, 3, 4, 5] # 直接赋值
chars = list("hello") # ['h', 'e', 'l', 'l', 'o']
from_range = list(range(5)) # [0, 1, 2, 3, 4]
squares = [x**2 for x in range(5)] # 列表推导式 → [0, 1, 4, 9, 16]
访问与切片
python
nums = [10, 20, 30, 40, 50]
# 索引
print(nums[0]) # 10
print(nums[-1]) # 50(负索引从尾部开始)
print(nums[-2]) # 40
# 切片 list[start:stop:step]
print(nums[1:4]) # [20, 30, 40](索引 1, 2, 3)
print(nums[:3]) # [10, 20, 30](从开头到索引 2)
print(nums[2:]) # [30, 40, 50](从索引 2 到末尾)
print(nums[::-1]) # [50, 40, 30, 20, 10](反转列表)
print(nums[::2]) # [10, 30, 50](步长为 2)
# 切片返回新列表(浅拷贝),不修改原列表
copied = nums[:]
print(copied is nums) # False --- 不同对象
常用方法
python
fruits = ["苹果", "香蕉"]
# 添加元素
fruits.append("橙子") # 末尾追加 → ["苹果", "香蕉", "橙子"]
fruits.extend(["葡萄", "西瓜"]) # 扩展多个 → ["苹果", "香蕉", "橙子", "葡萄", "西瓜"]
fruits.insert(1, "梨") # 在索引1处插入 → ["苹果", "梨", "香蕉", ...]
# 删除元素
fruits.remove("梨") # 删除第一个匹配值,不存在则 ValueError
last = fruits.pop() # 删除并返回末尾元素
second = fruits.pop(1) # 删除并返回索引1的元素
del fruits[0] # 按索引删除
fruits.clear() # 清空列表
# 查找与统计
nums = [1, 2, 3, 2, 4, 2]
print(nums.index(2)) # 1 --- 第一个 2 的索引
print(nums.index(2, 2)) # 3 --- 从索引2开始查找
print(nums.count(2)) # 3 --- 2 出现了 3 次
# 排序(原地修改)
nums.sort() # 升序
nums.sort(reverse=True) # 降序
words.sort(key=len) # 按长度排序
pairs.sort(key=lambda x: x[1]) # 按元组第二个元素排序
# 反转与拷贝
nums.reverse() # 原地反转
copy_nums = nums.copy() # 浅拷贝,等价于 nums[:]
列表的 + 和 *(注意陷阱)
python
# 拼接与重复
print([1, 2] + [3, 4]) # [1, 2, 3, 4]
print([0] * 5) # [0, 0, 0, 0, 0]
# ⚠️ 陷阱:[[]] * 3 是同一空列表的三份引用!
lists = [[]] * 3
lists[0].append(1)
print(lists) # [[1], [1], [1]] --- 三个元素指向同一个列表!
# ✅ 正确做法:用列表推导式创建独立嵌套列表
lists = [[] for _ in range(3)]
lists[0].append(1)
print(lists) # [[1], [], []] --- 三个独立的空列表
# 二维列表正确创建方式
matrix = [[0 for _ in range(4)] for _ in range(3)]
列表推导式(重要)
python
# 基本形式:[表达式 for 变量 in 可迭代对象]
squares = [x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 带条件过滤
evens = [x for x in range(20) if x % 2 == 0]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
# if-else 形式(注意顺序!)
labels = ["偶数" if x % 2 == 0 else "奇数" for x in range(5)]
# ['偶数', '奇数', '偶数', '奇数', '偶数']
# 嵌套循环(笛卡尔积)
pairs = [(x, y) for x in [1, 2] for y in ['a', 'b']]
# [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
# 同时遍历多个序列
names = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]
passed = [f"{n}: {s}" for n, s in zip(names, scores) if s >= 80]
# ['Alice: 85', 'Bob: 92']
2.2 元组 tuple --- 不可变有序序列
创建元组
python
# 创建方式
empty = () # 空元组
point = (1, 2, 3) # 多元素
single = (1,) # ⚠️ 单元素元组,逗号是关键!
not_tuple = (1) # 这只是带括号的整数,不是元组!
from_list = tuple([1, 2, 3]) # 从其他可迭代对象转换
print(type(single)) # <class 'tuple'>
print(type(not_tuple)) # <class 'int'> ← 注意!不是元组
特性与元组解包
python
# 不可变性
t = (1, 2, 3)
# t[0] = 10 # ❌ TypeError: 'tuple' object does not support item assignment
# 但如果元组包含可变对象,该可变对象内容可修改
t2 = (1, [2, 3], 4)
t2[1].append(5)
print(t2) # (1, [2, 3, 5], 4) --- 列表本身被修改了
# 元组解包(Tuple Unpacking)
a, b = (1, 2) # a=1, b=2
a, b, *rest = (1, 2, 3, 4, 5) # a=1, b=2, rest=[3,4,5]
first, *_, last = (1, 2, 3, 4, 5) # first=1, last=5, 忽略中间部分
# 实用:一行交换两个变量的值
a, b = b, a # 本质是元组解包
# 函数返回多个值(实际返回元组)
def min_max(nums):
return min(nums), max(nums)
low, high = min_max([3, 1, 4, 1, 5, 9])
print(low, high) # 1 9
2.3 字符串 str --- 不可变序列(Unicode)
创建与格式化
python
# 创建
s1 = '单引号'
s2 = "双引号"
s3 = '''多行
字符串''' # 三引号保留换行
s4 = str(100) # "100"
# ⭐ 字符串格式化(推荐优先级:f-string > format() > %)
# ① f-string(Python 3.6+,性能最优,最可读)
name = "Alice"
age = 30
print(f"我的名字是{name},明年{age + 1}岁")
# 格式化细节
pi = 3.1415926
print(f"圆周率:{pi:.2f}") # 圆周率:3.14
print(f"{12345678:,}") # 12,345,678(千分位)
print(f"{42:b}") # 101010(二进制)
print(f"{'Hello':>10}") # ' Hello'(右对齐宽度10)
print(f"{'Hello':0>10}") # '00000Hello'(左补零)
# ② str.format() 方法
print("{} {}".format("Hello", "World"))
print("{1} {0}".format("World", "Hello")) # 按位置序号
print("{name} {age}".format(name="Alice", age=25)) # 按关键字
# ③ % 格式化(旧式,不推荐新代码使用)
print("%s %d %f" % ("字符串", 123, 3.14))
常用方法
python
s = " Hello World "
# 大小写转换
print(s.upper()) # " HELLO WORLD "
print(s.lower()) # " hello world "
print(s.title()) # " Hello World "
print(s.capitalize()) # " hello world "(仅首字符大写)
# 判断类型(返回 bool)
print("abc".isalpha()) # True --- 全字母
print("123".isdigit()) # True --- 全数字
print("abc123".isalnum()) # True --- 字母或数字
print(" ".isspace()) # True --- 全空白
# 查找与替换
print(s.find("World")) # 8 --- 首次出现索引,未找到返回 -1
print(s.index("World")) # 8 --- 类似 find,但未找到引发 ValueError
print(s.count("l")) # 3 --- 统计出现次数
print(s.replace("World", "Python")) # " Hello Python "
# 分割与连接
print(s.split()) # ['Hello', 'World'] --- 默认按空白分割
print("a,b,c".split(",")) # ['a', 'b', 'c']
print("-".join(["a", "b", "c"])) # "a-b-c" --- ⭐ 高频使用!
# 修剪空白
print(s.strip()) # "Hello World" --- 移除两端空白
print(s.lstrip()) # "Hello World " --- 移除左侧
print(s.rstrip()) # " Hello World" --- 移除右侧
# 检查首尾
print("file.txt".endswith(".txt")) # True
print("http://example.com".startswith("http")) # True
编码与解码
python
# 字符串 → 字节
text = "你好"
bytes_data = text.encode("utf-8")
print(bytes_data) # b'\xe4\xbd\xa0\xe5\xa5\xbd'
# 字节 → 字符串
decoded_text = bytes_data.decode("utf-8")
print(decoded_text) # 你好
2.4 字典 dict --- 可变映射(Python 3.7+ 保序)
创建字典
python
# 多种创建方式
d1 = {} # 空字典
d2 = {"name": "Alice", "age": 25} # 直接赋值
d3 = dict(name="Alice", age=25) # 关键字参数
d4 = dict([("name", "Alice"), ("age", 25)]) # 键值对序列
d5 = dict.fromkeys(["a", "b", "c"], 0) # 批量创建相同值 → {'a': 0, 'b': 0, 'c': 0}
# ⚠️ 字典的键必须是不可变类型(可哈希)
valid_keys = {
"str": 1, # ✅ 字符串
123: 2, # ✅ 整数
3.14: 3, # ✅ 浮点数
(1, 2): 4, # ✅ 元组(元素也需全不可变)
}
# {[1, 2]: "bad"} # ❌ 列表不可作为键(可变,不可哈希)
基本操作
python
user = {"name": "Alice", "age": 25, "city": "北京"}
# ⭐ 取值(推荐用 get 方法避免 KeyError)
print(user["name"]) # Alice
# print(user["email"]) # ❌ KeyError: 'email'
print(user.get("email")) # None(键不存在不报错)
print(user.get("email", "未知")) # "未知"(提供默认值)
# 赋值与更新
user["age"] = 26 # 修改已有键
user["email"] = "alice@example.com" # 新增键值对
user.update({"phone": "123456", "city": "上海"}) # 批量更新
# setdefault:键存在返回对应值,不存在则设置默认值并返回
# 不存在的键 → 设置并返回默认值
# 已存在的键 → 返回原值,不修改
# 删除
del user["phone"] # 删除键,不存在则 KeyError
age = user.pop("age") # 删除并返回值,可提供默认值
last = user.popitem() # 删除并返回最后一个键值对(LIFO,3.7+)
user.clear() # 清空
# 成员检查(O(1) 平均复杂度)
if "name" in user:
print("存在 name 键")
# 遍历
for key in user: # 遍历键
print(key)
for value in user.values(): # 遍历值
print(value)
for key, value in user.items(): # ⭐ 遍历键值对(最常用)
print(f"{key}: {value}")
字典推导式
python
# 基本形式
squares = {x: x**2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# 带条件
evens = {x: x**2 for x in range(10) if x % 2 == 0}
# {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
# 反转键值对
original = {"a": 1, "b": 2, "c": 3}
reversed_dict = {v: k for k, v in original.items()}
# {1: 'a', 2: 'b', 3: 'c'}
2.5 集合 set / frozenset --- 无序不重复元素集
创建与特点
python
# ⚠️ 空集合必须用 set(),{} 创建的是空字典!
empty_set = set()
empty_dict = {}
print(type(empty_set)) # <class 'set'>
print(type(empty_dict)) # <class 'dict'>
# 创建非空集合
s = {1, 2, 3}
s2 = set([1, 2, 2, 3, 3]) # {1, 2, 3} --- 自动去重
s3 = set("hello") # {'h', 'e', 'l', 'o'} --- 注意顺序不固定且 l 只有一个
# 不可变集合
fs = frozenset([1, 2, 3]) # 不可修改,可哈希,可作为字典键
# 集合的元素必须是不可变类型
# {[1, 2]} # ❌ TypeError: unhashable type: 'list'
基本操作
python
s = {1, 2, 3}
# 添加与删除
s.add(4) # 添加元素
s.remove(4) # 删除元素,不存在则 KeyError
s.discard(4) # 删除元素,不存在也不报错(推荐)
popped = s.pop() # 随机删除并返回一个元素
s.clear() # 清空
# 成员检查(O(1) 平均复杂度)
print(2 in {1, 2, 3}) # True
# 集合推导式
evens_squared = {x**2 for x in range(10) if x % 2 == 0}
# {0, 64, 4, 36, 16} --- 注意集合是无序的
数学集合运算(集合的精华)
python
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
# 运算符方式(更直观)
print(a | b) # {1, 2, 3, 4, 5, 6} --- 并集
print(a & b) # {3, 4} --- 交集
print(a - b) # {1, 2} --- 差集
print(a ^ b) # {1, 2, 5, 6} --- 对称差集(在一边但不同时在两边)
# 方法方式(语义更明确)
print(a.union(b)) # 并集
print(a.intersection(b)) # 交集
print(a.difference(b)) # 差集
print(a.symmetric_difference(b)) # 对称差集
# 关系判断
print({1, 2} <= {1, 2, 3}) # True --- 子集
print({1, 2, 3} >= {1, 2}) # True --- 超集
print({1, 2}.isdisjoint({3, 4})) # True --- 无交集
# 去重(最常用场景)
items = [1, 2, 2, 3, 3, 3, 4]
unique = list(set(items))
print(unique) # [1, 2, 3, 4] --- 注意顺序可能变化
三、其它基础要点
3.1 真值测试(布尔上下文)
以下对象在布尔上下文中被视为 False(Falsy),其余均视为 True(Truthy):
python
# 所有 Falsy 值
falsy_values = [
False,
None,
0, 0.0, 0j, # 数字零值
"", # 空字符串
(), # 空元组
[], # 空列表
{}, # 空字典
set(), # 空集合
frozenset(), # 空不可变集合
]
for v in falsy_values:
print(f"{repr(v):15} → {bool(v)}")
# 利用真值测试简化代码
name = user_input or "默认名字" # user_input 为空时用默认值
items = data and data.get("items") or [] # 安全获取嵌套数据
3.2 三元表达式
python
age = 20
status = "成年" if age >= 18 else "未成年"
print(status) # 成年
# 可嵌套但不建议(可读性差)
x = "正" if num > 0 else ("零" if num == 0 else "负")
3.3 * 和 ** 解包运算符
python
# * 解包可迭代对象为位置参数
print(*[1, 2, 3]) # 等价于 print(1, 2, 3)
# ** 解包字典为关键字参数
def greet(name, age):
print(f"{name}, {age}岁")
greet(**{"name": "Alice", "age": 25}) # 等价于 greet(name="Alice", age=25)
# 合并列表 / 字典(创建新对象,不修改原对象)
list1, list2 = [1, 2], [3, 4]
combined_list = [*list1, *list2]
print(combined_list) # [1, 2, 3, 4]
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4} # 注意 "b" 重复
merged = {**dict1, **dict2} # 后者覆盖前者
print(merged) # {'a': 1, 'b': 3, 'c': 4}
3.4 type() 与 isinstance()
python
class Animal:
pass
class Dog(Animal):
pass
d = Dog()
print(type(d)) # <class '__main__.Dog'>
print(type(d) == Dog) # True
print(type(d) == Animal) # False --- 不匹配父类
print(isinstance(d, Dog)) # True
print(isinstance(d, Animal)) # True --- 子类属于父类实例
# ✅ 推荐多用 isinstance,它正确处理继承关系