用于快速回顾,内容覆盖基础语法、数据类型、运算符、流程控制、函数、模块、文件IO和面向对象。
用任意文本编辑器(记事本也行),写一个 .py 文件:
# 这是注释,不会执行
print("Hello World")命令行运行:
python hello.py如果提示找不到 python,检查是否装了 Python 且添加了 Path 环境变量。
推荐编辑器:
| 工具 | 特点 |
| VS Code | 免费、轻量、插件丰富(装 Python + Code Runner) |
| PyCharm | 专业 Python IDE,社区版免费 |
VS Code 中如果 Python 路径含空格导致 Run Code 失败,在 settings.json 的 code-runner 配置里给路径加引号就行。
Python3 源码默认 UTF-8 编码。需要改编码时,在文件头加:
# -*- coding: GBK -*-# 单行注释
"""
多行注释
可以写多行
"""Python 用缩进表示代码块,不用大括号。同一代码块缩进必须一致(建议 4 空格)。
if age >= 18:
print('adult')缩进不一致会报 IndentationError。
行尾加 \ 表示续行:
total = item_one + \
item_two + \
item_three在 []、{}、() 中不用加 \,直接换行即可。
变量 = 装数据的容器。
命名规则:
只能由字母、数字、下划线组成
不能数字开头
不能含空格和特殊符号
区分大小写
不能用关键字(35 个:False、None、True、and、as、assert、async、await、break、class、continue、def、del、elif、else、except、finally、for、from、global、if、import、in、is、lambda、nonlocal、not、or、pass、raise、return、try、while、with、yield)
不推荐覆盖内置函数名(如 list、print)
命名风格:
snake_case:普通变量,推荐
PascalCase:类名
camelCase:Python 中极少用
声明变量:
age = 25
name = "Alice"
a, b, c = 10, "hello", [4, 5] # 一行多变量
x = y = z = 99 # 多变量同值
m, n = n, m # 直接交换,不需要临时变量类型注解(仅提示,不强制):
score: int = 95
address: str = "北京"| 函数 | 说明 | 示例 |
| int() | 转整数 | int("123") → 123 |
| float() | 转浮点 | float("3.14") → 3.14 |
| str() | 转字符串 | str(123) → "123" |
| bool() | 转布尔 | bool(0) → False |
| list() | 转列表 | list((1,2,3)) → [1,2,3] |
| tuple() | 转元组 | tuple([1,2]) → (1,2) |
| dict() | 转字典 | dict([("a",1)]) → {"a":1} |
Python 没有 const 关键字,靠约定:全大写 + 下划线 表示常量。
PI = 3.1415926
MAX_SIZE = 100print("Hello") # 普通输出
print("姓名:", name, "年龄:", age) # 逗号分隔,自动加空格
print(x, end="") # 不换行6 大类:数字型、字符串、布尔型、序列型、字典、集合。
Python 是动态类型语言,变量类型由赋给它的值决定。
a = 10 # int(整数),无大小限制
b = 3.14 # float(浮点数)
c = 1.23e5 # 科学计数法 = 123000.0
d = 2 + 3j # complex(复数)不可变(不能 s[0]='A')
有序,索引从 0 开始
用 ' '、" " 或 ''' ''' 包裹
s = "hello\nworld" # \n 换行
s = r"hello\nworld" # r 表示原始字符串,不转义切片(核心操作):
str[起始:结束:步长] # 左闭右开s = "hello python"
s[0] # 'h'
s[1:4] # 'ell'
s[:3] # 'hel'
s[3:] # 'lo python'
s[-1:] # 'n'
s[::2] # 'hlopto'
s[::-1] # 反转字符串只有 True 和 False。规则:非 0 / 非空 = True,0 / 空 = False。
bool(0) # False
bool("") # False
bool([]) # False
bool(100) # True
bool("abc") # True可变、有序、用 [] 包裹,元素可混合类型。
lst = [1, 2, 3]
lst = list(range(0, 10, 2)) # [0, 2, 4, 6, 8]
lst = list("hello") # ['h','e','l','l','o']常用操作:
| 操作 | 说明 |
| lst.append(x) | 末尾追加 |
| lst.extend([x,y]) | 末尾扩展 |
| lst.insert(i, x) | 指定位置插入 |
| lst.pop(i) | 删除并返回(默认最后) |
| lst.remove(x) | 按值删除第一个 |
| lst[i] = x | 修改元素 |
| lst.index(x) | 查找索引 |
| lst.count(x) | 统计出现次数 |
| x in lst | 判断是否存在 |
| lst.sort() | 原地排序 |
| lst.reverse() | 原地反转 |
| sorted(lst) | 返回新排序列表 |
| lst[i:j:k] | 切片(同字符串) |
快捷操作:
lst1 + lst2 # 拼接
lst1 * 3 # 重复
len(lst) # 长度
max(lst) # 最大值
min(lst) # 最小值
sum(lst) # 求和和列表一样,但 不可修改。用 () 包裹。
t = (1, 2, 3)
t = 10, 20, 30 # 省略括号也行
single = (88,) # 单元素必须加逗号,否则是 int试图 t[0]=100 会报 TypeError。
但嵌套的可变元素(如列表)可以改:
t = (1, [2, 3], 4)
t[1][0] = 999 # 可以,因为改的是列表不是元组元组解包(实用):
a, b, c = (10, 20, 30) # 一一对应
first, *middle, last = (1,2,3,4,5) # middle = [2,3,4]生成整数序列,常配合 for 循环。
range(stop) # 0 ~ stop-1
range(start, stop) # start ~ stop-1
range(start, stop, step) # 指定步长list(range(5)) # [0,1,2,3,4]
list(range(2, 8)) # [2,3,4,5,6,7]
list(range(1,10,2)) # [1,3,5,7,9]
list(range(10,1,-3)) # [10,7,4]
r = range(0,10)
r[0] # 0
r[-1] # 9
r[2:7] # range(2,7)可变、无序(3.7+ 保持插入顺序)、键值对结构。用 {} 包裹,键必须唯一且不可变。
d = {"name": "张三", "age": 25}
d = dict(name="李四", age=30)
d = dict([("a",1), ("b",2)])
d = dict(zip(["x","y"], [10,20]))常用操作:
| 操作 | 说明 |
| d["key"] | 访问,键不存在报错 |
| d.get("key", 默认) | 安全访问,推荐 |
| d["key"] = v | 新增/修改 |
| d.setdefault(k, v) | 键存在返回值,不存在新增 |
| d.update({...}) | 批量更新 |
| del d["key"] | 删除 |
| d.pop("key") | 删除并返回值 |
| d.popitem() | 删除最后插入的键值对 |
| d.clear() | 清空 |
| "key" in d | 判断键是否存在 |
| d.keys() / d.values() / d.items() | 获取键/值/键值对 |
深浅拷贝:
d2 = d.copy() # 浅拷贝,嵌套对象共享
import copy
d2 = copy.deepcopy(d) # 深拷贝,完全独立合并(3.9+):
{"a":1, "b":2} | {"b":3, "c":4} # {'a':1, 'b':3, 'c':4}无序、不重复,用 {} 包裹。空集合必须用 set()。
s = {1, 2, 3}
s = set([1,2,2,3]) # 自动去重 → {1,2,3}| 操作 | 说明 |
| s.add(x) | 添加 |
| s.update([...]) | 批量添加 |
| s.remove(x) | 删除,不存在报错 |
| s.discard(x) | 删除,不存在不报错 |
| s.pop() | 随机删除一个 |
| s.clear() | 清空 |
集合运算:
a & b # 交集
a | b # 并集
a - b # 差集(a有b没有)
a ^ b # 对称差集(互不相同的)关系判断:issubset()、issuperset()、isdisjoint()
创建后不能修改,但可以当字典的键。
fs = frozenset([1,2,3])
# fs.add(4) 报错
d = {fs: "value"} # 可以作为字典键| 运算符 | 名称 | 示例 | 结果 | 说明 |
| + | 加 | 7 + 3 | 10 | 数字相加;字符串/列表可拼接 |
| - | 减 | 7 - 3 | 4 | 数字相减 |
| * | 乘 | 7 * 3 | 21 | 数字相乘;字符串/列表可重复 |
| / | 除 | 7 / 2 | 3.5 | 总是返回浮点数,即使能整除 |
| // | 整除 | 7 // 2 | 3 | 向下取整;负数注意:-7 // 2 = -4 |
| % | 取余 | 7 % 3 | 1 | 余数符号跟随被除数 |
| ** | 幂 | 2 ** 10 | 1024 | 右结合:2 ** 3 ** 2 = 512 |
7 / 2 # 3.5 (/ 永远是浮点除法)
7 // 2 # 3 (整除,向下取整)
-7 // 2 # -4 (-3.5 向下取整为 -4,而不是 -3)
7 % 3 # 1
-7 % 3 # 2 (余数符号跟随被除数)
2 ** 10 # 1024
2 ** 3 ** 2 # 512 (幂运算右结合,先算 3 ** 2)
# 字符串 / 列表也可以使用 + 和 *
"ab" + "cd" # "abcd"
"ab" * 3 # "ababab"
[1, 2] + [3] # [1, 2, 3]
[0] * 3 # [0, 0, 0]除法 / 永远返回浮点数;整除 // 和取余 % 在负数时按"向下取整"规则计算,容易踩坑。
| 运算符 | 含义 | 示例 | 结果 |
| == | 等于(比较值) | 3 == 3.0 | True |
| != | 不等于 | 3 != 4 | True |
| > | 大于 | 5 > 3 | True |
| < | 小于 | 5 < 3 | False |
| >= | 大于等于 | 5 >= 5 | True |
| <= | 小于等于 | 5 <= 4 | False |
比较结果永远是 True 或 False
支持链式比较:1 < a < 10 等价于 1 < a and a < 10
浮点数不要用 == 直接比较(存在二进制精度误差)
字符串按 Unicode 码点逐位比较
a = 8
1 < a < 10 # True,链式比较
# 浮点数比较陷阱
0.1 + 0.2 == 0.3 # False(二进制浮点误差)
abs((0.1 + 0.2) - 0.3) < 1e-9 # True,推荐这种写法
"apple" < "banana" # True,按字符码点比较| 运算符 | 等价写法 | 示例 |
| = | 直接赋值 | x = 10 |
| += | x = x + n | x += 5 |
| -= | x = x - n | x -= 5 |
| *= | x = x * n | x *= 5 |
| /= | x = x / n | x /= 5 |
| //= | x = x // n | x //= 5 |
| %= | x = x % n | x %= 5 |
| **= | x = x ** n | x **= 2 |
| &= | x = x & n | x &= 3 |
| |= | x = x | n | x |= 3 |
| ^= | x = x ^ n | x ^= 3 |
| >>= | x = x >> n | x >>= 1 |
| <<= | x = x << n | x <<= 1 |
海象运算符 :=(3.8+):在表达式中同时赋值并取值。
if (n := 10) > 5: # 先给 n 赋值为 10,再比较
print(n) # 10
# 经典场景:边读边判断
while (chunk := f.read(1024)):
process(chunk) # 读到空串时循环结束按二进制位进行运算:
| 运算符 | 名称 | 示例(二进制) | 结果 |
| & | 按位与 | 5 & 3(101 & 011) | 1 |
| | | 按位或 | 5 | 3(101 | 011) | 7 |
| ^ | 按位异或 | 5 ^ 3(101 ^ 011) | 6 |
| ~ | 按位取反 | ~5 | -6(~x = -x - 1) |
| << | 左移 | 5 << 1 | 10(相当于乘 2) |
| >> | 右移 | 5 >> 1 | 2(相当于整除 2) |
5 & 3 # 1 (101 & 011 = 001)
5 | 3 # 7 (101 | 011 = 111)
5 ^ 3 # 6 (101 ^ 011 = 110)
~5 # -6 (按位取反,~x = -x - 1)
5 << 1 # 10 (左移 1 位,相当于乘 2)
5 >> 1 # 2 (右移 1 位,相当于整除 2)
# 常见用途:用位做开关标记
flags = 0b0000
flags |= 0b0001 # 打开第 1 位
flags |= 0b0010 # 打开第 2 位
flags & 0b0001 # 1,判断第 1 位是否开启| 运算符 | 含义 | 说明 | 示例 |
| and | 且 | 两边都为真才为真 | True and False → False |
| or | 或 | 一边为真就为真 | True or False → True |
| not | 非 | 取反 | not True → False |
短路规则(返回值是操作数本身,不一定是布尔):
and:第一个为假,直接返回第一个;否则返回第二个
or:第一个为真,直接返回第一个;否则返回第二个
0 and 20 # 0
10 and 20 # 20
0 or 20 # 20
10 or 20 # 10
not 0 # True
not "abc" # False
# 实用写法:取默认值
name = user_name or "匿名用户" # user_name 为空就用默认值判断元素是否在序列(字符串、列表、元组、集合)中;字典判断的是键。
"a" in "abc" # True
3 in [1, 2, 3] # True
"x" not in "abc" # True
"age" in {"name":"张三", "age":25} # True,字典判断键is / is not:比较两个变量是否指向同一个对象(比内存地址);== 比较的是值。
a = [1, 2, 3]
b = [1, 2, 3]
a == b # True(值相等)
a is b # False(不是同一个对象)
# 小整数缓存:-5 ~ 256 的整数是同一个对象
x = 100
y = 100
x is y # True(缓存导致指向同一对象)
# 判断 None 必须用 is
if x is None:
...不要用 is 判断数值相等(超出缓存范围会出错);判断 None 时不要用 ==。
| 优先级 | 运算符 | 说明 |
| 1 | () | 括号优先 |
| 2 | ** | 幂(右结合) |
| 3 | +x、-x、~x | 正负号、按位取反 |
| 4 | *、/、//、% | 乘、除、整除、取余 |
| 5 | +、- | 加、减 |
| 6 | <<**、**>> | 移位 |
| 7 | & | 按位与 |
| 8 | ^ | 按位异或 |
| 9 | | | 按位或 |
| 10 | ==、!=、>、<**、**>=、<= | 比较 |
| 11 | not | 逻辑非 |
| 12 | and | 逻辑与 |
| 13 | or | 逻辑或 |
| 14 | := | 海象赋值 |
2 + 3 * 4 # 14,乘法先算
(2 + 3) * 4 # 20,括号改变优先级
2 ** 3 ** 2 # 512,幂右结合,先算 3 ** 2
not 0 and 1 # 1,先 not 再 and记不住优先级没关系,用括号明确表达意图,代码可读性优先。
name = input("请输入姓名:")
print(f"你输入的是:{name}")# 单分支
if 条件:
代码块
# 双分支
if 条件:
代码块
else:
代码块
# 多分支
if 条件1:
代码块
elif 条件2:
代码块
else:
代码块三元表达式:
result = "及格" if score >= 60 else "不及格"注意:if-elif 要把严格条件放在前面,否则会被宽松条件"吃掉"。
while 条件:
循环体
else: # 正常结束(非break)才执行
passfor 变量 in 可迭代对象:
循环体
else: # 正常遍历完才执行
pass常用遍历:
for i in range(5): # 数字序列
for char in "hello": # 字符串
for item in [1,2,3]: # 列表
for key, val in dict.items(): # 字典键值对
for idx, val in enumerate(lst): # 索引+元素嵌套 for:典型如九九乘法表。
break:终止整个循环
continue:跳过本次,进入下一次
pass:占位,什么都不做
def 函数名(参数列表):
"""文档字符串"""
函数体
return 返回值 # 可选,不写默认返回Nonedef add(a, b):
return a + b
result = add(3, 5) # 调用默认参数:
def add(a, b=0):
return a + b关键字参数(调用时按参数名传):
print_info(age=18, name="小李")不定长参数:
| 参数 | 说明 |
| *args | 接收多个位置参数,打包成元组 |
| **kwargs | 接收多个关键字参数,打包成字典 |
def func(a, b, *args, c=0, **kwargs):
pass
func(1, 2, 3, 4, c=10, x=100, y=200)
# a=1, b=2, args=(3,4), c=10, kwargs={'x':100,'y':200}
# 拆包传递
nums = [1, 2, 3]
add(*nums) # 等价 add(1,2,3)
d = {"name":"小王","age":20}
print_person(**d) # 等价 print_person(name="小王",age=20)lambda 参数: 表达式f = lambda x: x * 2
sorted(lst, key=lambda x: x[1]) # 按第二个元素排序
filter(lambda x: x % 2 == 0, nums) # 筛选偶数
map(lambda x: x**2, nums) # 批量平方| 函数 | 说明 |
| filter(函数, 可迭代对象) | 过滤,保留返回 True 的元素 |
| map(函数, 可迭代对象) | 对每个元素执行相同操作 |
| reduce(函数, 可迭代对象) | 累积计算(需 from functools import reduce) |
from functools import reduce
reduce(lambda x, y: x + y, [1,2,3,4]) # 10
reduce(lambda x, y: x + y, [1,2,3,4], 10) # 20查找顺序:局部 → 嵌套 → 全局 → 内置。
| 关键字 | 作用 |
| global | 在函数内声明使用全局变量 |
| nonlocal | 在嵌套函数内声明使用外层函数的变量 |
count = 0
def outer():
x = 10
def inner():
nonlocal x
x = 20 # 修改的是 outer 里的 x
inner()
print(x) # 20| 类别 | 函数 |
| 数学 | abs() round() max() min() sum() pow() |
| 类型转换 | int() float() str() bool() list() tuple() set() dict() |
| 进制 | bin() oct() hex() |
| 其他 | len() type() range() enumerate() zip() sorted() |
import 模块名 # 导入整个模块
import 模块名 as 别名 # 起别名
from 模块名 import 成员 # 导入指定成员
from 模块名 import 成员 as 别名 # 成员起别名
from 模块名 import * # 导入所有(不推荐)| 模块 | 用途 |
| sys | 解释器交互(sys.argv、sys.path) |
| os | 操作系统交互(文件/目录操作) |
| math | 数学函数(math.pi、math.sqrt()) |
| datetime | 日期时间处理 |
| json | JSON 编解码 |
| random | 随机数生成 |
一个 .py 文件就是一个模块。同目录下的 main.py 可以直接 import my_module。
运行后会自动生成 pycache 目录存放 .pyc 字节码缓存,加速下次导入。
Python 按 sys.path 列表顺序查找模块:
当前脚本所在目录
PYTHONPATH 环境变量
Python 标准库目录
site-packages(第三方库)
import sys
sys.path.append("/自定义路径") # 临时添加pip install 模块名 # 安装最新版
pip install 模块名==版本号 # 安装指定版本
pip install --upgrade 模块名 # 升级
pip uninstall 模块名 # 卸载
pip list # 查看已安装
pip show 模块名 # 查看模块信息
pip freeze > requirements.txt # 导出依赖清单
pip install -r requirements.txt # 按清单安装镜像加速:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 模块名包 = 含 init.py 的文件夹,用于组织模块。
mypackage/
├── __init__.py # 包标识 + 导出控制
├── module_a.py
├── module_b.py
└── sub_pkg/
├── __init__.py
└── utils.pyinit.py 常用写法:
from .module_a import func_a
from .module_b import func_b
__all__ = ["func_a", "func_b"] # 控制 from package import * 的导出# 创建
python -m venv venv
# 激活(Windows)
venv\Scripts\activate.bat
# 激活(Linux/Mac)
source venv/bin/activate
# 退出
deactivate其他工具:virtualenv(兼容 Python2)、conda(Anaconda 自带,适合数据科学)。
绝对路径:从根目录开始的完整路径
Windows:C:\Users\xxx\file.txt
Linux:/home/user/file.txt
相对路径:相对于程序当前运行目录
. 当前目录、.. 上级目录
Windows 中 **** 需写成 \\ 或用原始字符串 r"路径"
open(file, mode='r', encoding=None, ...)mode 模式:
| 模式 | 说明 |
| r | 只读(默认),文件必须存在 |
| w | 只写,清空后写入,不存在则创建 |
| a | 追加,在末尾写入 |
| r+ | 读写,文件必须存在 |
| w+ | 读写,先清空 |
| a+ | 追加+读写 |
| b | 二进制模式(如 rb、wb) |
| t | 文本模式(默认) |
encoding:推荐始终指定 encoding="utf-8",避免中文乱码。
自动管理资源,代码块结束自动关闭文件,即使异常也能安全关闭。
with open("test.txt", "r", encoding="utf-8") as f:
content = f.read()| 方法 | 说明 |
| f.read() | 一次性读取全部,适合小文件 |
| f.readline() | 逐行读,适合需要逐行处理 |
| f.readlines() | 返回所有行的列表,适合小文件 |
| for line in f: | 逐行迭代,适合大文件(内存占用低) |
读大文件(如 10GB)必须用逐行迭代,不能一次全读。
f.seek(偏移量, 参考位置)
# 参考位置: 0=开头, 1=当前位置, 2=末尾
f.tell() # 查看当前指针位置f.seek(0) # 回到开头
f.seek(0, 2) # 移到末尾
f.seek(-10, 2) # 从末尾往前 10 字节覆盖写(谨慎!会清空原内容):
with open("test.txt", "w", encoding="utf-8") as f:
f.write("新内容")追加写(推荐,不丢数据):
with open("test.txt", "a", encoding="utf-8") as f:
f.write("追加的内容\n")面向过程:按步骤写函数,顺序调用
面向对象:以对象为核心,通过对象交互实现功能
OOP 四大特性:封装、继承、多态、抽象。
类:模板/图纸,定义属性和方法
对象:类的具体实例
class 类名: # 大驼峰命名
"""文档字符串"""
# 类属性(所有实例共享)
species = "人类"
# 构造方法
def __init__(self, name, age):
self.name = name # 实例属性
self.age = age
# 实例方法
def introduce(self):
print(f"我叫{self.name},今年{self.age}岁")
# 类方法
@classmethod
def class_method(cls):
pass
# 静态方法
@staticmethod
def static_method():
passp1 = Person("张三", 20)
p1.introduce() # 我叫张三,今年20岁
print(p1.name) # 访问属性self:代表实例本身,方法第一个参数必须写(约定命名)
init():构造方法,创建对象时自动调用
name == "main":判断脚本是否直接运行
if __name__ == "__main__":
# 直接运行这个脚本时执行
p = Person("测试", 18)
p.introduce()到这里,Python 基础语法就介绍完了,后续将持续更新。