入门教程
下面是一份面向零基础、基于 Python 3.12 的入门教程。建议按照章节顺序学习,并亲手运行每一段代码。
Python 是一种简洁、易读、功能强大的编程语言,常用于:
- 自动化办公
- 数据分析
- 网络爬虫
- Web 开发
- 人工智能
- 科学计算
- 运维脚本
- 股票数据处理
Python 程序通常按照从上到下的顺序执行。
第一个 Python 程序:
print("Hello, Python!")
运行结果:
Hello, Python!
在终端或命令提示符中运行:
python --version
部分系统需要使用:
python3 --version
输出类似:
Python 3.12.10
python3
进入后可以直接执行:
>>> 1 + 2
3
退出交互环境:
exit()
创建文件:
hello.py
写入:
print("你好,Python")
运行:
python3 hello.py
单行注释使用 #:
# 这是一个注释
print("Hello")
多行说明通常使用多个 #:
# 计算商品总价
# 商品单价为 10 元
# 购买数量为 5 个
total = 10 * 5
也可以使用三引号编写文档字符串:
"""
这是一个多行说明。
通常用于函数、类和模块的文档。
"""
Python 使用缩进表示代码层级,一般使用四个空格:
age = 20
if age >= 18:
print("成年人")
下面的代码会报错:
if age >= 18:
print("成年人")
以下变量是三个不同的变量:
name = "Tom"
Name = "Jerry"
NAME = "Alice"
变量用于保存数据。
name = "张三"
age = 25
height = 1.75
其中:
- name 保存字符串
- age 保存整数
- height 保存小数
变量名可以包含:
- 字母
- 数字
- 下划线
但是不能以数字开头。
正确示例:
user_name = "Martin"
age2 = 30
stock_code = "600519"
错误示例:
2age = 30
user-name = "Martin"
推荐使用小写字母和下划线:
total_price = 100
user_age = 25
name, age, city = "张三", 25, "成都"
也可以给多个变量赋同一个值:
a = b = c = 0
name = "张三"
age = 25
print(type(name))
print(type(age))
结果:
<class 'str'>
<class 'int'>
Python 常见数据类型包括:
| 类型 | 名称 | 示例 |
|---|---|---|
| int | 整数 | 10 |
| float | 浮点数 | 3.14 |
| str | 字符串 | “Python” |
| bool | 布尔值 | True |
| NoneType | 空值 | None |
Python 是动态类型语言,不用声明类型,但是可以添加类型注解,方便阅读代码。
age: int = 30
count: int = -10
number: int = 0
Python 整数没有固定长度限制:
large_number: int = 123456789012345678901234567890
print(large_number)
price: float = 12.5
temperature: float = -3.8
浮点数计算可能出现精度误差:
print(0.1 + 0.2)
结果可能是:
0.30000000000000004
财务计算需要精确小数时,可以使用 Decimal:
from decimal import Decimal
result = Decimal("0.1") + Decimal("0.2")
print(result)
结果:
0.3
字符串可以使用单引号或双引号:
name: str = "Python"
city: str = '成都'
多行字符串:
text: str = """
第一行
第二行
第三行
"""
布尔值只有两个:
True
False
例如:
is_open: bool = True
is_deleted: bool = False
注意首字母必须大写。
result: None = None
None 表示当前没有值:
if result is None:
print("暂时没有结果")
age: int = int("25")
print(age)
字符串必须是合法整数:
int("25") # 正确
int("25.5") # 报错
浮点数转换为整数时,小数部分会被直接删除:
number: int = int(3.99)
print(number)
结果:
3
price: float = float("19.9")
age: int = 25
text: str = str(age)
以下值转换为布尔值时为 False:
False
None
0
0.0
""
[]
{}
set()
其他大多数值为 True:
print(bool(1))
print(bool("Python"))
print(bool([1, 2]))
print("Hello")
print(100)
print(3.14)
一次输出多个值:
name = "张三"
age = 25
print(name, age)
指定分隔符:
print("2026", "07", "10", sep="-")
结果:
2026-07-10
指定结尾:
print("Hello", end=" ")
print("Python")
结果:
Hello Python
name = input("请输入你的名字:")
print("你好,", name)
input() 返回的数据永远是字符串。
例如:
age = input("请输入年龄:")
print(type(age))
即使输入 25,类型仍然是 str。
需要转换:
age = int(input("请输入年龄:"))
print(age + 1)
first_name = "张"
last_name = "三"
full_name = first_name + last_name
print(full_name)
字符串不能直接和整数拼接:
age = 25
# 错误
print("年龄:" + age)
正确写法:
print("年龄:" + str(age))
更推荐使用格式化字符串。
格式化字符串,使用 f 前缀。
name = "张三"
age = 25
print(f"姓名:{name},年龄:{age}")
表达式也可以写在大括号中:
price = 20
count = 3
print(f"总价:{price * count} 元")
控制小数位数:
price = 12.34567
print(f"{price:.2f}")
结果:
12.35
text = "Python"
print(text[0])
print(text[1])
print(text[-1])
结果:
P
y
n
索引从 0 开始。
基本格式:
字符串[开始位置:结束位置:步长]
示例:
text = "Python"
print(text[0:3])
print(text[:3])
print(text[3:])
print(text[::-1])
结果:
Pyt
Pyt
hon
nohtyP
切片不包含结束位置。
text = " Hello Python "
print(text.strip()) # 去掉首尾空格
print(text.lower()) # 转为小写
print(text.upper()) # 转为大写
print(text.replace("Python", "World")) # 替换
判断开头和结尾:
code = "600519"
print(code.startswith("60")) # 判断开头
print(code.endswith("19")) # 判断结尾
查找内容:
text = "Python is easy"
print(text.find("easy")) # 查找
print("Python" in text) # 判断包含
分割字符串:
codes = "600519,000001,300750"
code_list = codes.split(",") # 分割
print(code_list) # ['600519', '000001', '300750']
连接字符串:
words = ["Python", "Java", "Go"]
result = "、".join(words) # 连接
print(result) # Python、Java、Go
+ - * / // % **
a = 10
b = 3
print(a + b) # 加法
print(a - b) # 减法
print(a * b) # 乘法
print(a / b) # 除法
print(a // b) # 整除
print(a % b) # 取余
print(a ** b) # 幂运算
== != > < >= <=
a = 10
b = 20
print(a == b)
print(a != b)
print(a > b)
print(a < b)
print(a >= b)
print(a <= b)
比较结果是布尔值。
and or not
所有条件都成立,结果才成立:
age = 25
has_ticket = True
print(age >= 18 and has_ticket)
至少一个条件成立即可:
day = "星期六"
print(day == "星期六" or day == "星期日")
对结果取反:
is_closed = False
print(not is_closed)
in not in is is not
stocks = ["贵州茅台", "宁德时代", "比亚迪"]
print("贵州茅台" in stocks)
print("工商银行" not in stocks)
print("贵州茅台" is "宁德时代")
print("贵州茅台" is not "比亚迪")
number = 10
number += 5
number -= 2
number *= 3
number /= 2
age = 20
if age >= 18:
print("你已经成年")
age = 16
if age >= 18:
print("成年人")
else:
print("未成年人")
score = 85
if score >= 90:
print("优秀")
elif score >= 80:
print("良好")
elif score >= 60:
print("及格")
else:
print("不及格")
条件判断从上到下执行,满足一个条件后,后面的分支不再执行。
age = 20
has_ticket = True
if age >= 18:
if has_ticket:
print("允许进入")
else:
print("请先购票")
else:
print("年龄不符合要求")
普通写法:
age = 20
if age >= 18:
result = "成年"
else:
result = "未成年"
简化写法:
result = "成年" if age >= 18 else "未成年"
Python 3.10 及以上支持结构模式匹配:
status = 404
match status:
case 200:
print("请求成功")
case 404:
print("资源不存在")
case 500:
print("服务器错误")
case _:
print("未知状态")
_ 表示其他情况。
遍历列表:
names = ["张三", "李四", "王五"]
for name in names:
print(name)
遍历字符串:
for char in "Python":
print(char)
生成数字序列:
for number in range(5):
print(number)
结果:
0
1
2
3
4
指定开始位置:
for number in range(1, 6):
print(number)
指定步长:
for number in range(0, 10, 2):
print(number)
结果:
0
2
4
6
8
count = 1
while count <= 5:
print(count)
count += 1
注意修改循环条件,否则可能出现死循环。
立即结束循环:
for number in range(1, 11):
if number == 5:
break
print(number)
结果:
1
2
3
4
跳过当前循环:
for number in range(1, 6):
if number == 3:
continue
print(number)
结果:
1
2
4
5
占位符,不执行任何操作:
for number in range(1, 6):
if number == 3:
pass
同时获取索引和值:
names = ["张三", "李四", "王五"]
for index, name in enumerate(names):
print(index, name)
从 1 开始编号:
for index, name in enumerate(names, start=1):
print(index, name)
同时遍历多个序列:
names = ["张三", "李四", "王五"]
scores = [80, 90, 75]
for name, score in zip(names, scores):
print(name, score)
列表用于保存一组有顺序、可修改的数据。
stocks = ["贵州茅台", "比亚迪", "宁德时代"]
print(stocks[0])
print(stocks[-1])
stocks[0] = "五粮液"
末尾添加:
stocks.append("中国平安")
指定位置插入:
stocks.insert(1, "招商银行")
一次添加多个元素:
stocks.extend(["中际旭创", "工业富联"])
按照值删除:
stocks.remove("比亚迪")
按照索引删除并返回:
deleted_stock = stocks.pop(0)
删除指定位置:
del stocks[1]
清空列表:
stocks.clear()
print(len(stocks))
numbers = [5, 2, 9, 1]
numbers.sort()
print(numbers)
降序:
numbers.sort(reverse=True)
不修改原列表:
numbers = [5, 2, 9, 1]
new_numbers = sorted(numbers)
numbers = [55, 66, 66, 77, 88]
print(numbers.count(66)) # 2
print(numbers.index(77)) # 3
print(max(numbers)) # 88
print(min(numbers)) # 55
print(sum(numbers)) # 352
numbers = [10, 20, 30, 40, 50]
print(numbers[1:4]) # [20, 30, 40]
print(numbers[:3]) # [10, 20, 30]
print(numbers[::-1]) # [50, 40, 30, 20, 10]
普通写法:
squares = []
for number in range(1, 6):
squares.append(number ** 2)
列表推导式:
squares = [number ** 2 for number in range(1, 6)]
带条件:
even_numbers = [
number
for number in range(1, 11)
if number % 2 == 0
]
元组和列表相似,但创建后不能修改。
- 不可变
point = (10, 20)
访问元素:
print(point[0])
元组不能修改:
point[0] = 100
上面的代码会报错。
必须保留逗号:
value = (10,)
下面不是元组:
value = (10)
name, age, city = ("张三", 25, "成都")
print(name)
print(age)
print(city)
交换变量:
a = 10
b = 20
a, b = b, a
字典使用键值对保存数据。
stock = {
"code": "600519",
"name": "贵州茅台",
"price": 1500.0,
}
stock.keys()
stock.values()
print(stock["name"])
使用不存在的键会报错:
print(stock["industry"])
更安全的方法:
print(stock.get("industry"))
print(stock.get("industry", "未知行业"))
stock["industry"] = "白酒"
stock["price"] = 1520.0
stock.pop("price")
或者:
del stock["industry"]
遍历键:
- 使用 for 循环,默认迭代键。
for key in stock:
print(key)
遍历值:
for value in stock.values():
print(value)
同时遍历键和值:
for key, value in stock.items():
print(key, value)
if "code" in stock:
print(stock["code"])
squares = {
number: number ** 2
for number in range(1, 6)
}
结果:
{
1: 1,
2: 4,
3: 9,
4: 16,
5: 25,
}
集合是一组无序、不重复的数据。
- 去重 + 集合运算
numbers = {1, 2, 3, 3, 4}
print(numbers)
结果中重复的 3 会被自动删除。
numbers = set()
注意:
value = {}
创建的是空字典,不是空集合。
numbers.add(5)
numbers.remove(2)
numbers.discard(10)
remove() 删除不存在的元素会报错。
discard() 删除不存在的元素不会报错。
a = {1, 2, 3}
b = {3, 4, 5}
print(a | b) # 并集
print(a & b) # 交集
print(a - b) # 差集
print(a ^ b) # 对称差集
集合常用于数据去重:
codes = ["600519", "000001", "600519"]
unique_codes = list(set(codes))
函数用于封装可重复执行的代码。
def greet():
print("你好")
调用函数:
greet()
def greet(name):
print(f"你好,{name}")
调用:
greet("张三")
def add(a, b):
return a + b
调用:
result = add(10, 20)
print(result)
return 会结束函数执行。
def greet(name, message="你好"): # message 有默认参数
print(f"{message},{name}")
调用:
greet("张三")
greet("李四", "早上好")
def create_user(name, age, city):
print(name, age, city)
调用时指定参数名:
create_user(
city="成都",
name="张三",
age=25,
)
经典示例:
def foo(*args, **kwargs):
pass
接收任意数量的位置参数:
def total(*numbers):
return sum(numbers)
调用:
print(total(1, 2, 3, 4))
numbers 在函数内部是元组。
接收任意数量的关键字参数:
def show_user(**user):
print(user)
调用:
show_user(
name="张三",
age=25,
city="成都",
)
user 在函数内部是字典。
Python 3.12 支持类型提示:
def add(a: int, b: int) -> int:
return a + b
字符串参数和返回值:
def format_code(code: str) -> str:
return code.strip()
类型提示不会自动限制类型,但可以提高代码可读性,并帮助编辑器发现问题。
def add(a: int, b: int) -> int:
"""
计算两个整数之和。
参数:
a: 第一个整数
b: 第二个整数
返回:
两个整数的和
"""
return a + b
查看文档:
help(add)
- Local 局部
- Enclosing 闭包
- Global 全局
- Built-in 内置
函数内部定义的变量通常只能在函数内部使用:
def test():
message = "Hello"
print(message)
下面会报错:
print(message)
全局变量:
message = "Hello"
def show():
print(message)
不建议在函数中频繁修改全局变量。
Lambda 用于编写简单的匿名函数。
普通函数:
def square(number):
return number ** 2
Lambda 写法:
square = lambda number: number ** 2
使用:
print(square(5))
常用于排序:
stocks = [
{"name": "A公司", "price": 20},
{"name": "B公司", "price": 10},
{"name": "C公司", "price": 30},
]
stocks.sort(key=lambda stock: stock["price"])
print(stocks)
复杂逻辑不建议使用 Lambda。
程序运行时可能发生错误,例如:
- 输入格式错误
- 文件不存在
- 除数为零
- 字典键不存在
try:
number = int(input("请输入整数:"))
print(number)
except ValueError:
print("输入内容不是合法整数")
try:
a = int(input("请输入第一个数字:"))
b = int(input("请输入第二个数字:"))
print(a / b)
except ValueError:
print("请输入合法数字")
except ZeroDivisionError:
print("除数不能为零")
没有发生异常时执行:
try:
number = int(input("请输入整数:"))
except ValueError:
print("输入错误")
else:
print(f"输入成功:{number}")
无论是否发生异常都会执行:
try:
print("执行程序")
finally:
print("程序结束")
def set_age(age: int) -> None:
if age < 0:
raise ValueError("年龄不能小于零")
print(f"年龄:{age}")
with open(
"example.txt",
"w",
encoding="utf-8",
) as file:
file.write("第一行\n")
file.write("第二行\n")
w 表示写入模式,会覆盖原文件。
with open(
"example.txt",
"a",
encoding="utf-8",
) as file:
file.write("第三行\n")
a 表示追加模式。
with open(
"example.txt",
"r",
encoding="utf-8",
) as file:
content = file.read()
print(content)
with open(
"example.txt",
"r",
encoding="utf-8",
) as file:
for line in file:
print(line.strip())
现代 Python 更推荐使用 pathlib:
from pathlib import Path
file_path = Path("example.txt")
file_path.write_text(
"Hello Python",
encoding="utf-8",
)
content = file_path.read_text(
encoding="utf-8",
)
print(content)
判断文件是否存在:
if file_path.exists():
print("文件存在")
创建目录:
folder = Path("data")
folder.mkdir(
parents=True,
exist_ok=True,
)
JSON 是程序之间交换数据的常见格式。
import json
stock = {
"code": "600519",
"name": "贵州茅台",
"price": 1500.0,
}
json_text = json.dumps(
stock,
ensure_ascii=False,
indent=2,
)
print(json_text)
import json
json_text = """
{
"code": "600519",
"name": "贵州茅台"
}
"""
stock = json.loads(json_text)
print(stock["name"])
import json
data = {
"name": "张三",
"age": 25,
}
with open(
"user.json",
"w",
encoding="utf-8",
) as file:
json.dump(
data,
file,
ensure_ascii=False,
indent=2,
)
import json
with open(
"user.json",
"r",
encoding="utf-8",
) as file:
data = json.load(file)
print(data)
一个 Python 文件就是一个模块。
假设存在文件:
calculator.py
内容:
def add(a: int, b: int) -> int:
return a + b
def subtract(a: int, b: int) -> int:
return a - b
在另一个文件中导入:
import calculator
result = calculator.add(10, 20)
print(result)
只导入某个函数:
from calculator import add
print(add(10, 20))
设置别名:
import calculator as calc
print(calc.add(10, 20))
import math
print(math.sqrt(16)) # 平方根, 4.0
print(math.ceil(3.2)) # 向上取整, 3
print(math.floor(3.8)) # 向下取整, 4
import random
print(random.randint(1, 10))
随机选择:
names = ["张三", "李四", "王五"]
print(random.choice(names))
from datetime import datetime
now = datetime.now()
print(now)
print(now.strftime("%Y-%m-%d %H:%M:%S"))
import statistics
numbers = [10, 20, 30, 40]
print(statistics.mean(numbers)) # 平均值
print(statistics.median(numbers)) # 中位数
Python 自带的库叫标准库。
其他开发者编写的库叫第三方库,需要使用 pip 安装。
查看 pip 版本:
python3 -m pip --version
安装库:
python3 -m pip install requests
卸载库:
python3 -m pip uninstall requests
查看已经安装的库:
python3 -m pip list
虚拟环境用于隔离不同项目的依赖。
python3 -m venv .venv
macOS 或 Linux:
source .venv/bin/activate
Windows PowerShell:
.venv\Scripts\Activate.ps1
Windows CMD:
.venv\Scripts\activate.bat
激活后,终端通常会显示:
(.venv)
deactivate
python3 -m pip freeze > requirements.txt
安装项目依赖:
python3 -m pip install -r requirements.txt
面向对象用于把数据和行为组织在一起。
class Person:
def __init__(self, name: str, age: int):
self.name = name
self.age = age
def introduce(self) -> None:
print(f"我叫{self.name},今年{self.age}岁")
创建对象:
person = Person("张三", 25)
person.introduce()
self 表示当前对象本身。
self.name
表示当前对象的 name 属性。
class Person:
species = "人类"
def __init__(self, name: str):
self.name = name
访问类属性:
print(Person.species)
# 父类
class Animal:
def speak(self) -> None:
print("动物发出声音")
# 子类 (继承 Animal)
class Dog(Animal):
def speak(self) -> None:
print("汪汪")
使用:
dog = Dog()
dog.speak()
Python 3.12 中,可以使用 dataclass 简化数据类:
from dataclasses import dataclass
@dataclass
class Stock:
code: str
name: str
price: float
创建对象:
stock = Stock(
code="600519",
name="贵州茅台",
price=1500.0,
)
print(stock)
生成器使用 yield 返回数据:
def number_generator():
yield 1
yield 2
yield 3
使用:
for number in number_generator():
print(number)
生成器不会一次性把所有数据放入内存,适合处理大量数据。
numbers = (
number ** 2
for number in range(1, 6)
)
for number in numbers:
print(number)
列表推导式使用方括号:
[number ** 2 for number in range(1, 6)]
生成器表达式使用圆括号:
(number ** 2 for number in range(1, 6))
print(len("Python"))
print(len([1, 2, 3]))
print(sum([10, 20, 30]))
numbers = [10, 5, 20]
print(max(numbers))
print(min(numbers))
numbers = [3, 1, 2]
new_numbers = sorted(numbers)
print(round(3.14159, 2))
print(abs(-10))
所有元素都为真时返回 True:
print(all([True, True, True]))
至少一个元素为真时返回 True:
print(any([False, False, True]))
numbers = [1, 2, 3]
result = map(
lambda number: number ** 2,
numbers,
)
print(list(result))
在简单场景下,通常更推荐列表推导式:
result = [
number ** 2
for number in numbers
]
numbers = [1, 2, 3, 4, 5]
result = filter(
lambda number: number % 2 == 0,
numbers,
)
print(list(result))
也可以使用列表推导式:
result = [
number
for number in numbers
if number % 2 == 0
]
Python 3.12 可以直接使用内置类型编写类型提示:
def get_names() -> list[str]:
return ["张三", "李四"]
字典类型:
def get_stock() -> dict[str, str]:
return {
"code": "600519",
"name": "贵州茅台",
}
可选值:
def find_name(user_id: int) -> str | None:
if user_id == 1:
return "张三"
return None
多个可能的类型:
def format_value(value: int | float | str) -> str:
return str(value)
类型别名:
type StockCode = str
def normalize_code(code: StockCode) -> StockCode:
return code.strip()
type 类型别名语法是 Python 3.12 的新语法之一。
泛型函数:
def first[T](items: list[T]) -> T | None:
if not items:
return None
return items[0]
这也是 Python 3.12 支持的新泛型语法。
Python 文件可以直接运行,也可以被其他文件导入。
def main() -> None:
print("程序开始运行")
if __name__ == "__main__":
main()
当文件被直接运行时:
__name__ == "__main__"
条件成立。
当文件被其他模块导入时,main() 不会自动执行。
推荐将程序入口写成:
def main() -> None:
pass
if __name__ == "__main__":
main()
if age >= 18:
print("成年人")
user_name = "张三"
stock_code = "600519"
class StockAnalyzer:
pass
MAX_RETRY_COUNT = 3
DEFAULT_TIMEOUT = 10
不推荐:
def process_everything():
# 读取文件
# 清洗数据
# 发送请求
# 保存数据库
pass
推荐拆分:
def read_data():
pass
def clean_data():
pass
def save_data():
pass
不推荐:
if condition1:
if condition2:
if condition3:
print("执行")
可以使用提前返回:
def process(
condition1: bool,
condition2: bool,
condition3: bool,
) -> None:
if not condition1:
return
if not condition2:
return
if not condition3:
return
print("执行")
需求:
- 参数必须是字符串
- 长度必须是 6 位
- 以 00 开头,转换为 33-00
- 以 60 开头,转换为 17-60
- 其他代码返回原值
def convert_code(code: str) -> str:
"""
根据股票代码开头转换代码格式。
"""
if not isinstance(code, str):
raise TypeError("code 必须是字符串")
if len(code) != 6:
raise ValueError("code 长度必须为 6 位")
if not code.isdigit():
raise ValueError("code 必须全部由数字组成")
if code.startswith("00"):
return f"33-{code[:2]}"
if code.startswith("60"):
return f"17-{code[:2]}"
return code
def main() -> None:
codes = [
"000001",
"600519",
"300750",
]
for code in codes:
result = convert_code(code)
print(code, result)
if __name__ == "__main__":
main()
运行结果:
000001 33-00
600519 17-60
300750 300750
contacts: dict[str, str] = {}
def add_contact(name: str, phone: str) -> None:
contacts[name] = phone
print("联系人添加成功")
def find_contact(name: str) -> None:
phone = contacts.get(name)
if phone is None:
print("没有找到联系人")
return
print(f"{name}:{phone}")
def show_contacts() -> None:
if not contacts:
print("通讯录为空")
return
for name, phone in contacts.items():
print(f"{name}:{phone}")
def main() -> None:
while True:
print("\n1. 添加联系人")
print("2. 查找联系人")
print("3. 显示全部联系人")
print("4. 退出")
choice = input("请选择:").strip()
match choice:
case "1":
name = input("请输入姓名:").strip()
phone = input("请输入电话:").strip()
add_contact(name, phone)
case "2":
name = input("请输入姓名:").strip()
find_contact(name)
case "3":
show_contacts()
case "4":
print("程序结束")
break
case _:
print("无效选项")
if __name__ == "__main__":
main()
def count_words(text: str) -> dict[str, int]:
words = text.lower().split()
result: dict[str, int] = {}
for word in words:
result[word] = result.get(word, 0) + 1
return result
def main() -> None:
text = "Python is easy Python is powerful"
word_counts = count_words(text)
for word, count in word_counts.items():
print(word, count)
if __name__ == "__main__":
main()
运行结果:
python 2
is 2
easy 1
powerful 1
import json
from pathlib import Path
def load_stocks(file_path: Path) -> list[dict[str, object]]:
if not file_path.exists():
raise FileNotFoundError(f"文件不存在:{file_path}")
text = file_path.read_text(encoding="utf-8")
data = json.loads(text)
if not isinstance(data, list):
raise ValueError("JSON 根节点必须是列表")
return data
def show_stocks(stocks: list[dict[str, object]]) -> None:
for stock in stocks:
code = stock.get("code", "")
name = stock.get("name", "")
price = stock.get("price", 0)
print(f"{code} {name} {price}")
def main() -> None:
file_path = Path("stocks.json")
try:
stocks = load_stocks(file_path)
except FileNotFoundError as error:
print(error)
except json.JSONDecodeError:
print("JSON 文件格式错误")
except ValueError as error:
print(error)
else:
show_stocks(stocks)
if __name__ == "__main__":
main()
stocks.json 示例:
[
{
"code": "600519",
"name": "贵州茅台",
"price": 1500.0
},
{
"code": "000001",
"name": "平安银行",
"price": 11.5
}
]
语法错误:
if age >= 18
print("成年")
缺少冒号。
正确:
if age >= 18:
print("成年")
使用了不存在的变量:
print(user_name)
需要先定义:
user_name = "张三"
print(user_name)
类型不匹配:
"年龄:" + 25
正确:
"年龄:" + str(25)
或者:
f"年龄:{25}"
值的格式不正确:
int("abc")
列表索引超出范围:
numbers = [1, 2, 3]
print(numbers[10])
字典键不存在:
user = {"name": "张三"}
print(user["age"])
可以使用:
print(user.get("age"))
对象没有对应方法或属性:
number = 100
number.append(1)
整数没有 append() 方法。
- 变量
- 数据类型
- 输入输出
- 运算符
- 条件判断
- 循环
- 字符串
- 列表
- 元组
- 字典
- 集合
- 函数
- 异常处理
- 文件操作
- JSON
- 模块和包
- 面向对象
- 类型提示
- 生成器
- 虚拟环境
- 第三方库
可以选择一个方向:
- Excel 自动化
- 股票数据分析
- 网络爬虫
- 数据库操作
- Web API
- 文件批量处理
- 日常办公自动化
输入姓名和年龄,输出:
你好,张三,你明年 26 岁。
参考思路:
name = input("请输入姓名:")
age = int(input("请输入年龄:"))
print(f"你好,{name},你明年 {age + 1} 岁。")
输入一个整数,判断奇数还是偶数。
number = int(input("请输入整数:"))
if number % 2 == 0:
print("偶数")
else:
print("奇数")
计算 1 到 100 的总和。
total = 0
for number in range(1, 101):
total += number
print(total)
也可以直接使用:
print(sum(range(1, 101)))
找出列表中的最大值,但不使用 max()。
numbers = [10, 35, 12, 80, 6]
largest = numbers[0]
for number in numbers[1:]:
if number > largest:
largest = number
print(largest)
删除列表中的重复元素,并保持原顺序。
numbers = [1, 2, 2, 3, 1, 4]
result = []
for number in numbers:
if number not in result:
result.append(number)
print(result)
统计字符串中每个字符出现的次数。
text = "hello"
counts = {}
for char in text:
counts[char] = counts.get(char, 0) + 1
print(counts)
编写函数,判断股票代码是否合法。
规则:
- 必须是字符串
- 长度为 6 位
- 全部由数字组成
def is_valid_stock_code(code: str) -> bool:
return (
isinstance(code, str)
and len(code) == 6
and code.isdigit()
)
简单项目可以使用以下目录:
stock_project/
├── .venv/
├── data/
│ └── stocks.json
├── src/
│ ├── __init__.py
│ ├── loader.py
│ └── analyzer.py
├── tests/
│ └── test_analyzer.py
├── main.py
├── requirements.txt
└── README.md
main.py:
from src.loader import load_data
from src.analyzer import analyze_data
def main() -> None:
data = load_data()
result = analyze_data(data)
print(result)
if __name__ == "__main__":
main()
这种结构能够把:
- 数据读取
- 数据处理
- 程序入口
- 测试代码
分别组织起来。
学习完本教程后,应当能够:
- 创建和使用变量。
- 理解整数、浮点数、字符串和布尔值。
- 使用条件判断处理不同情况。
- 使用循环批量处理数据。
- 使用列表、字典和集合组织数据。
- 编写带参数和返回值的函数。
- 读取和写入文本及 JSON 文件。
- 使用异常处理提高程序稳定性。
- 创建虚拟环境并安装第三方库。
- 编写结构清晰的小型 Python 项目。
真正掌握 Python 的关键不是记住所有语法,而是不断完成以下过程:
明确需求
→ 拆分步骤
→ 编写代码
→ 运行测试
→ 阅读错误
→ 修改代码
→ 总结规律
编程能力主要来自持续实践,而不是单纯阅读。