Basics基础语法
Python groups code with indentation, not braces — its most defining rule. The convention is 4 spaces, and indentation must be consistent within a block. Python 用缩进而不是花括号来划分代码块,这是它最鲜明的规则。约定用 4 个空格,同一层级缩进必须一致。
# Comments# 注释
# A single-line comment starts with a hash
x = 42 # can also trail a statement
"""
Triple quotes hold a multi-line string,
often used as documentation (a docstring).
"""
# 单行注释以井号开头
x = 42 # 也可以写在语句末尾
"""
三引号可以写多行字符串,
常被当作文档字符串(docstring)使用。
"""Variables & assignment变量与赋值
No type declarations — just assign. Types are dynamic, bound to the value rather than the variable. 变量无需声明类型,直接赋值即可;类型是动态的,绑定在值上而非变量上。
name = "Ada" # str
age = 36 # int
height = 1.70 # float
is_admin = True # bool
# Multiple assignment and unpacking
a, b = 1, 2
a, b = b, a # swap, no temp needed
x = y = z = 0 # chained assignment
print(name, age, is_admin)
name = "Ada" # str
age = 36 # int
height = 1.70 # float
is_admin = True # bool
# 多重赋值与解包
a, b = 1, 2
a, b = b, a # 交换,无需临时变量
x = y = z = 0 # 链式赋值
print(name, age, is_admin)Output & input输出与输入
print("Hello", "World", sep=", ", end="!\n")
name = input("What's your name? ") # input always returns str
age = int(input("How old? ")) # convert when you need a number
print(f"{name} is {age} years old")
print("Hello", "World", sep=", ", end="!\n")
name = input("你叫什么名字? ") # input 永远返回 str
age = int(input("几岁? ")) # 需要数字时手动转换
print(f"{name} 今年 {age} 岁")Built-in Types数据类型
Python ships a small set of core types. Use type(x) to inspect and isinstance(x, T) to test. Python 内置了一组核心类型。用 type(x) 查看类型,用 isinstance(x, T) 做判断。
| Type类型 | Example示例 | Notes说明 |
|---|---|---|
int | 42 -7 0xFF | Integers, unlimited size, no overflow整数,任意大小,无溢出 |
float | 3.14 2.0e3 | Double-precision float双精度浮点数 |
complex | 3+4j | Complex numbers复数 |
bool | True False | Boolean, a subclass of int布尔,是 int 的子类 |
str | "text" | Immutable sequence of characters不可变的字符序列 |
list | [1, 2, 3] | Ordered, mutable sequence有序、可变序列 |
tuple | (1, 2) | Ordered, immutable sequence有序、不可变序列 |
dict | {"k": 1} | Key-value mapping键值映射 |
set | {1, 2, 3} | Unordered, unique items无序、不重复集合 |
NoneType | None | Means "empty / no value"表示"空 / 没有值" |
# Type checking and conversion
print(type(42)) # <class 'int'>
print(isinstance(3.14, float)) # True
int("100") # string to int -> 100
str(3.14) # number to string -> "3.14"
float("2.5") # -> 2.5
bool(0), bool(""), bool([]) # all False ("falsy")
# 类型检查与转换
print(type(42)) # <class 'int'>
print(isinstance(3.14, float)) # True
int("100") # 字符串转整数 -> 100
str(3.14) # 数字转字符串 -> "3.14"
float("2.5") # -> 2.5
bool(0), bool(""), bool([]) # 都是 False("假值")Operators运算符
| Category类别 | Operators运算符 | Example例子 |
|---|---|---|
| Arithmetic算术 | + - * / // % ** | 7 // 2 → 3 (floor), 2 ** 10 → 10247 // 2 → 3(整除),2 ** 10 → 1024 |
| Comparison比较 | == != < > <= >= | 3 < 5 → True |
| Logical逻辑 | and or not | x > 0 and x < 10 |
| Assignment赋值 | = += -= *= /= … | n += 1 |
| Membership成员 | in not in | "a" in "cat" → True |
| Identity身份 | is is not | x is None |
| Bitwise位运算 | & | ^ ~ << >> | 5 & 3 → 1 |
10 / 3 # 3.3333333333333335 (true division, always float)
10 // 3 # 3 (floor division)
10 % 3 # 1 (remainder)
2 ** 8 # 256 (power)
# Chained comparison, reads like math
0 < age < 120
# Ternary expression
label = "adult" if age >= 18 else "minor"
10 / 3 # 3.3333333333333335 (真除法,总是 float)
10 // 3 # 3 (向下取整)
10 % 3 # 1 (取余)
2 ** 8 # 256 (幂)
# 链式比较,符合数学直觉
0 < age < 120
# 三元表达式
label = "成年" if age >= 18 else "未成年"Strings字符串
Strings are immutable. Prefer the f-string for formatting — concise and clear. 字符串不可变。推荐用 f-string 做格式化——简洁又直观。
s = "Python"
# f-string: put expressions inside braces
name, score = "Ada", 96.5
print(f"{name} scored {score:.1f}") # Ada scored 96.5
print(f"{name.upper()} · length {len(name)}")
# Indexing and slicing [start:stop:step]
s[0] # 'P'
s[-1] # 'n' (negative index counts from the end)
s[0:3] # 'Pyt'
s[::-1] # 'nohtyP' (reverse)
# Common methods
" hi ".strip() # 'hi'
"a,b,c".split(",") # ['a', 'b', 'c']
"-".join(["2024","07","30"]) # '2024-07-30'
"Hello".replace("l", "L") # 'HeLLo'
"cat".startswith("ca") # True
s = "Python"
# f-string:大括号里放表达式
name, score = "Ada", 96.5
print(f"{name} 得了 {score:.1f} 分") # Ada 得了 96.5 分
print(f"{name.upper()} · 长度 {len(name)}")
# 索引与切片 [start:stop:step]
s[0] # 'P'
s[-1] # 'n' (负索引从末尾数)
s[0:3] # 'Pyt'
s[::-1] # 'nohtyP' (反转)
# 常用方法
" hi ".strip() # 'hi'
"a,b,c".split(",") # ['a', 'b', 'c']
"-".join(["2024","07","30"]) # '2024-07-30'
"Hello".replace("l", "L") # 'HeLLo'
"cat".startswith("ca") # True| Prefix前缀 | Meaning含义 | Example例子 |
|---|---|---|
f"..." | Formatted string格式化字符串 | f"{1+1}" → "2" |
r"..." | Raw string, no escapes原始串,不转义 | r"\n" is two charsr"\n" 是两个字符 |
b"..." | Bytes字节串 bytes | b"data" |
Collections数据结构
Four containers: list, tuple, dict, set. Grasp "mutable vs immutable" and "ordered vs unordered" and you've got the essentials. 四大容器:列表、元组、字典、集合。记住"可变 vs 不可变"和"有序 vs 无序"就抓住了要点。
list — ordered, mutable列表 list 有序可变
nums = [3, 1, 4, 1, 5]
nums.append(9) # add to the end
nums.insert(0, 2) # insert at an index
nums.remove(1) # remove the first 1
last = nums.pop() # pop and return the last item
nums.sort() # sort in place
nums[1:3] = [10, 20] # slice assignment
len(nums), max(nums), sum(nums)
nums = [3, 1, 4, 1, 5]
nums.append(9) # 末尾添加
nums.insert(0, 2) # 指定位置插入
nums.remove(1) # 删除第一个 1
last = nums.pop() # 弹出并返回末尾
nums.sort() # 原地排序
nums[1:3] = [10, 20] # 切片赋值
len(nums), max(nums), sum(nums)tuple — ordered, immutable元组 tuple 有序不可变
point = (3, 4)
x, y = point # unpacking
point[0] # 3
# point[0] = 9 -> error: tuples are immutable
single = (42,) # a single-element tuple needs a comma
point = (3, 4)
x, y = point # 解包
point[0] # 3
# point[0] = 9 -> 报错:元组不可修改
single = (42,) # 单元素元组要带逗号dict — key-value mapping字典 dict 键值映射
user = {"name": "Ada", "age": 36}
user["email"] = "ada@x.io" # add / update
user.get("phone", "N/A") # safe lookup with a default
"name" in user # True
for key, value in user.items():
print(key, "=", value)
user.keys() # all keys
user.values() # all values
user = {"name": "Ada", "age": 36}
user["email"] = "ada@x.io" # 新增 / 修改
user.get("phone", "无") # 安全取值,带默认
"name" in user # True
for key, value in user.items():
print(key, "=", value)
user.keys() # 所有键
user.values() # 所有值set — dedup + set algebra集合 set 去重 + 集合运算
a = {1, 2, 3}
b = {3, 4, 5}
a | b # union {1,2,3,4,5}
a & b # intersection {3}
a - b # difference {1,2}
set([1,1,2,2,3]) # quick dedup -> {1,2,3}
a = {1, 2, 3}
b = {3, 4, 5}
a | b # 并集 {1,2,3,4,5}
a & b # 交集 {3}
a - b # 差集 {1,2}
set([1,1,2,2,3]) # 快速去重 -> {1,2,3}Control Flow控制流
Conditionals — if / elif / else条件 — if / elif / else
score = 82
if score >= 90:
grade = "A"
elif score >= 60:
grade = "B"
else:
grade = "C"
score = 82
if score >= 90:
grade = "A"
elif score >= 60:
grade = "B"
else:
grade = "C"Loops — for / while循环 — for / while
# for iterates over any iterable
for i in range(3): # 0, 1, 2
print(i)
for i, item in enumerate(["a", "b"]): # with an index
print(i, item)
for k, v in zip(["x", "y"], [1, 2]): # parallel iteration
print(k, v)
# while loops on a condition
n = 5
while n > 0:
n -= 1
# break exits, continue skips this round
for x in range(10):
if x == 3: continue
if x == 6: break
print(x)
# for 遍历任意可迭代对象
for i in range(3): # 0, 1, 2
print(i)
for i, item in enumerate(["a", "b"]): # 带下标
print(i, item)
for k, v in zip(["x", "y"], [1, 2]): # 并行遍历
print(k, v)
# while 条件循环
n = 5
while n > 0:
n -= 1
# break 跳出,continue 跳过本轮
for x in range(10):
if x == 3: continue
if x == 6: break
print(x)Pattern matching — match / case (3.10+)模式匹配 — match / case (3.10+)
def describe(cmd):
match cmd.split():
case ["go", direction]:
return f"heading {direction}"
case ["quit"]:
return "quitting"
case _:
return "unknown command" # _ is the wildcard
def describe(cmd):
match cmd.split():
case ["go", direction]:
return f"前往 {direction}"
case ["quit"]:
return "退出"
case _:
return "未知指令" # _ 是通配Functions函数
Define with def, return with return; with no return, a function gives back None. 用 def 定义,return 返回;没有 return 时默认返回 None。
def greet(name, greeting="Hello"): # parameter with a default
"""Return a greeting (this is a docstring)."""
return f"{greeting}, {name}!"
greet("Ada") # Hello, Ada!
greet("Ada", greeting="Hi") # keyword argument, order-free
# *args collects positional args, **kwargs collects keyword args
def total(*nums, **opts):
s = sum(nums)
return s * opts.get("factor", 1)
total(1, 2, 3, factor=10) # 60
# lambda: a small throwaway function
square = lambda x: x * x
sorted(["bb", "a", "ccc"], key=lambda s: len(s))
# Type hints (optional, hints only)
def add(a: int, b: int) -> int:
return a + b
def greet(name, greeting="你好"): # 带默认值的参数
"""返回一句问候(这是 docstring)。"""
return f"{greeting}, {name}!"
greet("Ada") # 你好, Ada!
greet("Ada", greeting="Hi") # 关键字参数,顺序无所谓
# *args 收集位置参数,**kwargs 收集关键字参数
def total(*nums, **opts):
s = sum(nums)
return s * opts.get("factor", 1)
total(1, 2, 3, factor=10) # 60
# lambda:一次性小函数
square = lambda x: x * x
sorted(["bb", "a", "ccc"], key=lambda s: len(s))
# 类型注解(可选,仅作提示)
def add(a: int, b: int) -> int:
return a + bComprehensions推导式
Build a new collection from an iterable in a single line — one of the most idiomatic Python patterns. 一行写出"从可迭代对象生成新集合"的逻辑,是 Python 最地道的写法之一。
# List comprehension: [expr for item in iterable if cond]
squares = [x**2 for x in range(10)]
evens = [x for x in range(20) if x % 2 == 0]
matrix = [[r*c for c in range(3)] for r in range(3)]
# Dict comprehension
sq_map = {x: x**2 for x in range(5)} # {0:0, 1:1, 2:4, ...}
# Set comprehension
initials = {name[0] for name in ["Ada", "Alan", "Bob"]}
# Generator expression: parentheses, lazy, memory-friendly
total = sum(x**2 for x in range(1_000_000))
# 列表推导:[表达式 for 变量 in 可迭代 if 条件]
squares = [x**2 for x in range(10)]
evens = [x for x in range(20) if x % 2 == 0]
matrix = [[r*c for c in range(3)] for r in range(3)]
# 字典推导
sq_map = {x: x**2 for x in range(5)} # {0:0, 1:1, 2:4, ...}
# 集合推导
initials = {name[0] for name in ["Ada", "Alan", "Bob"]}
# 生成器表达式:用圆括号,惰性求值、省内存
total = sum(x**2 for x in range(1_000_000))Exceptions异常处理
try:
value = int(input("Enter a number: "))
result = 10 / value
except ValueError:
print("That's not a number")
except ZeroDivisionError:
print("Can't divide by zero")
else:
print("Success:", result) # runs only if no error
finally:
print("Always runs") # good for cleanup
# Raise an exception yourself
def withdraw(balance, amount):
if amount > balance:
raise ValueError("Insufficient balance")
return balance - amount
try:
value = int(input("输入一个数: "))
result = 10 / value
except ValueError:
print("那不是数字")
except ZeroDivisionError:
print("不能除以零")
else:
print("成功:", result) # 没出错才执行
finally:
print("无论如何都会执行") # 常用于清理
# 主动抛出异常
def withdraw(balance, amount):
if amount > balance:
raise ValueError("余额不足")
return balance - amount| Exception常见异常 | When it fires触发场景 |
|---|---|
ValueError | Invalid value, e.g. int("abc")值不合法,如 int("abc") |
TypeError | Wrong type, e.g. "a" + 1类型不对,如 "a" + 1 |
KeyError | Key not in the dict字典里没有该键 |
IndexError | Sequence index out of range序列下标越界 |
FileNotFoundError | File does not exist文件不存在 |
Classes & OOP类与面向对象
__init__ is the constructor; self refers to the instance. Methods wrapped in double underscores are "dunder" (magic) methods. __init__ 是构造方法,self 指向实例本身。以双下划线包裹的方法叫"魔术方法(dunder)"。
class Animal:
def __init__(self, name): # constructor
self.name = name # instance attribute
def speak(self):
return f"{self.name} makes a sound"
def __repr__(self): # how it looks when printed
return f"Animal({self.name!r})"
# Inheritance: Dog is an Animal
class Dog(Animal):
def speak(self): # method override
return f"{self.name}: Woof!"
def fetch(self):
return f"{self.name} fetches the ball"
d = Dog("Rex")
print(d.speak()) # Rex: Woof!
isinstance(d, Animal) # True (Dog inherits from Animal)
class Animal:
def __init__(self, name): # 构造方法
self.name = name # 实例属性
def speak(self):
return f"{self.name} 发出声音"
def __repr__(self): # 决定 print 时的样子
return f"Animal({self.name!r})"
# 继承:Dog 是一种 Animal
class Dog(Animal):
def speak(self): # 方法重写
return f"{self.name}: 汪汪!"
def fetch(self):
return f"{self.name} 去捡球"
d = Dog("旺财")
print(d.speak()) # 旺财: 汪汪!
isinstance(d, Animal) # True(Dog 继承自 Animal)| Dunder魔术方法 | Purpose作用 |
|---|---|
__init__ | Initialize on creation创建实例时初始化 |
__repr__ / __str__ | Text representation of the object对象的文本表示 |
__len__ | Supports len(obj)支持 len(obj) |
__eq__ | Supports ==支持 == 比较 |
__iter__ | Makes it iterable in a for loop让对象可被 for 遍历 |
Modules & Packages模块与包
import math # import the whole module
from math import pi, sqrt # import only what you need
from datetime import datetime as dt # alias
import os, sys # import several at once
math.sqrt(16) # 4.0
pi # 3.141592653589793
# Common guard: run only when this file is executed directly
if __name__ == "__main__":
main()
import math # 导入整个模块
from math import pi, sqrt # 只导入需要的名字
from datetime import datetime as dt # 起别名
import os, sys # 一次导入多个
math.sqrt(16) # 4.0
pi # 3.141592653589793
# 常见守卫:只有直接运行本文件时才执行
if __name__ == "__main__":
main()File I/O文件读写
Open files with with — they close automatically when the block ends, so you never forget close(). 用 with 打开文件,离开代码块时会自动关闭——不会忘记 close。
# Write (w overwrites, a appends)
with open("notes.txt", "w", encoding="utf-8") as f:
f.write("first line\n")
f.writelines(["second line\n", "third line\n"])
# Read
with open("notes.txt", "r", encoding="utf-8") as f:
content = f.read() # read it all in
# or iterate line by line:
with open("notes.txt", encoding="utf-8") as f:
for line in f:
print(line.rstrip())
# Read / write JSON
import json
with open("data.json", "w", encoding="utf-8") as f:
json.dump({"ok": True}, f, ensure_ascii=False)
# 写入(w 覆盖,a 追加)
with open("notes.txt", "w", encoding="utf-8") as f:
f.write("第一行\n")
f.writelines(["第二行\n", "第三行\n"])
# 读取
with open("notes.txt", "r", encoding="utf-8") as f:
content = f.read() # 整体读入
# 或逐行遍历:
with open("notes.txt", encoding="utf-8") as f:
for line in f:
print(line.rstrip())
# 读写 JSON
import json
with open("data.json", "w", encoding="utf-8") as f:
json.dump({"ok": True}, f, ensure_ascii=False)Decorators · Generators装饰器 · 生成器
Decorators装饰器
A decorator is a "function that wraps a function" — the @ syntax enhances a function without changing its body. 装饰器是"包装函数的函数",用 @ 语法在不改动原函数的前提下增强它。
import time
from functools import wraps
def timer(func):
@wraps(func) # keep the original name and docs
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
print(f"{func.__name__} took {time.perf_counter()-start:.4f}s")
return result
return wrapper
@timer # same as slow = timer(slow)
def slow():
time.sleep(0.5)
slow()
import time
from functools import wraps
def timer(func):
@wraps(func) # 保留原函数名与文档
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
print(f"{func.__name__} 用时 {time.perf_counter()-start:.4f}s")
return result
return wrapper
@timer # 等价于 slow = timer(slow)
def slow():
time.sleep(0.5)
slow()Generators生成器
yield hands out values one at a time, lazily — ideal for large data streams. 用 yield 逐个"产出"值,惰性求值,适合处理大数据流。
def countdown(n):
while n > 0:
yield n # each yield hands out a value and pauses
n -= 1
for x in countdown(3): # 3, 2, 1
print(x)
# Fibonacci sequence, never fills memory
def fib():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
gen = fib()
[next(gen) for _ in range(8)] # [0,1,1,2,3,5,8,13]
def countdown(n):
while n > 0:
yield n # 每次 yield 交出一个值并暂停
n -= 1
for x in countdown(3): # 3, 2, 1
print(x)
# 斐波那契数列,永不占满内存
def fib():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
gen = fib()
[next(gen) for _ in range(8)] # [0,1,1,2,3,5,8,13]Standard Library常用标准库
"Batteries included" — Python ships a large set of ready-to-use modules. "电池已包含"——Python 自带大量开箱即用的模块。
| Module模块 | Purpose用途 | Common常用 |
|---|---|---|
os / pathlib | Paths & filesystem路径与文件系统 | Path("a")/"b" |
sys | Interpreter & CLI args解释器与命令行参数 | sys.argv |
math | Math functions数学函数 | math.gcd |
random | Random numbers随机数 | random.choice |
datetime | Dates & times日期与时间 | datetime.now() |
json | JSON serializationJSON 序列化 | json.loads |
re | Regular expressions正则表达式 | re.findall |
collections | Enhanced containers增强容器 | Counter, defaultdict |
itertools | Iterator tools迭代器工具 | chain, groupby |
from collections import Counter
from pathlib import Path
import random, datetime
Counter("mississippi") # {'i':4, 's':4, 'p':2, 'm':1}
random.randint(1, 6) # roll a die
datetime.date.today().isoformat() # '2024-07-30'
Path("docs").glob("*.md") # iterate every .md file
from collections import Counter
from pathlib import Path
import random, datetime
Counter("mississippi") # {'i':4, 's':4, 'p':2, 'm':1}
random.randint(1, 6) # 掷骰子
datetime.date.today().isoformat() # '2024-07-30'
Path("docs").glob("*.md") # 遍历所有 .md 文件venv & pip虚拟环境与 pip
Create an isolated environment per project so dependencies don't clash — the first step of professional development. 每个项目建一个独立的虚拟环境,依赖互不干扰——这是专业开发的第一步。
# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate # macOS / Linux
.venv\Scripts\activate # Windows
# Install / manage third-party packages with pip
pip install requests
pip install "django>=5.0"
pip list # installed packages
pip freeze > requirements.txt # export the dependency list
pip install -r requirements.txt # install from the list
deactivate # leave the virtual environment
# 创建并激活虚拟环境
python -m venv .venv
source .venv/bin/activate # macOS / Linux
.venv\Scripts\activate # Windows
# 用 pip 安装 / 管理第三方包
pip install requests
pip install "django>=5.0"
pip list # 已装的包
pip freeze > requirements.txt # 导出依赖清单
pip install -r requirements.txt # 按清单安装
deactivate # 退出虚拟环境The Zen of PythonPython 之禅
Type import this in the interpreter to see the design philosophy Tim Peters wrote. It's the best starting point for understanding how Python should be written. 在解释器里输入 import this,会看到 Tim Peters 写下的设计哲学。这是理解"Python 该怎么写"的最好起点。
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Readability counts.
If the implementation is hard to explain, it's a bad idea.
There should be one obvious way to do it.
优美胜于丑陋 Beautiful is better than ugly.
明了胜于晦涩 Explicit is better than implicit.
简单胜于复杂 Simple is better than complex.
可读性很重要 Readability counts.
如果实现难以解释,那它就是个坏主意。
If the implementation is hard to explain, it's a bad idea.
应该有一种,最好只有一种,显而易见的做法。
There should be one obvious way to do it.Keep these in mind and your code is already "Pythonic". The rest comes with practice. 把这几条放在心上,你写出的就已经是"Pythonic"的代码了。剩下的,交给练习。