1. Python入门第二天:从基础语法到实战小项目
如果你已经完成了Python第一天的学习,对print()、变量和基本数据类型有了初步认识,那么第二天就该开始真正动手写代码了。作为一门以"简单易学"著称的语言,Python在第二天就能让你体会到编程的乐趣。我会带你从基础语法过渡到第一个完整的小项目,过程中会分享我初学Python时踩过的坑和私藏技巧。
2. 基础语法巩固与提升
2.1 条件判断的隐藏技巧
if-else语句看似简单,但Python特有的简洁写法值得掌握。比如这个三目运算符替代方案:
python复制age = 18
status = "成年" if age >= 18 else "未成年"
比传统写法更Pythonic。但要注意:过度使用会降低可读性,建议只在简单赋值时采用。
新手常犯的错误是误用=代替==,我建议在判断相等时把常量放前面:
python复制if 18 == age: # 这样写如果漏写一个=会直接报错
print("刚成年")
2.2 循环结构的性能陷阱
while和for循环的区别不仅仅是语法形式。计算1到100的和时:
python复制# 方式一:while
total = 0
i = 1
while i <= 100:
total += i
i += 1 # 新手常忘记这行导致死循环
# 方式二:for
total = sum(range(1, 101)) # Pythonic写法
第二种写法的优势:
- 更简洁
- 避免忘记更新循环变量
- 内置函数性能更好
经验:能用for就别用while,Python的迭代协议让for循环效率更高
2.3 列表操作的进阶玩法
列表推导式是Python的招牌特性,但容易滥用:
python复制# 好的用法
squares = [x**2 for x in range(10) if x % 2 == 0]
# 不易读的写法(应避免)
result = [y for x in data if condition(x) for y in process(x)]
记住:如果推导式超过一行,就该考虑改用普通for循环。
切片操作有个实用技巧——逆序:
python复制nums = [1, 2, 3, 4, 5]
reverse_nums = nums[::-1] # [5, 4, 3, 2, 1]
3. 函数定义与使用规范
3.1 参数传递的坑
Python的参数传递既不是传值也不是传引用,而是"传对象引用"。这导致一个经典问题:
python复制def append_item(item, lst=[]):
lst.append(item)
return lst
print(append_item(1)) # [1]
print(append_item(2)) # [1, 2] 而不是预期的[2]
解决方法是用None作为默认值:
python复制def append_item(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
3.2 类型提示的妙用
虽然Python是动态类型,但类型提示能提高代码质量:
python复制from typing import List
def greet_all(names: List[str]) -> None:
for name in names:
print(f"Hello, {name}!")
用mypy工具可以静态检查类型错误,这对大型项目特别有用。
4. 文件操作实战
4.1 安全读写文件
新手常犯的错误是忘记关闭文件:
python复制# 危险写法
f = open('data.txt')
content = f.read()
# 如果中间抛出异常,文件不会关闭
f.close()
应该使用with语句:
python复制with open('data.txt') as f:
content = f.read()
# 自动关闭文件
4.2 处理不同编码
遇到编码错误时,不要盲目用ignore:
python复制# 错误方式
with open('data.txt', encoding='utf-8', errors='ignore') as f:
...
# 正确做法
try:
with open('data.txt', encoding='utf-8') as f:
content = f.read()
except UnicodeDecodeError:
# 尝试其他编码
with open('data.txt', encoding='gbk') as f:
content = f.read()
5. 实战项目:天气查询工具
5.1 项目结构设计
code复制weather_app/
├── main.py # 主程序
├── utils.py # 工具函数
└── test_utils.py # 单元测试
这种简单结构适合小型项目,避免过早引入复杂架构。
5.2 使用requests库
安装第三方库时,建议使用虚拟环境:
bash复制python -m venv venv
source venv/bin/activate # Linux/Mac
venv\Scripts\activate # Windows
pip install requests
基础请求示例:
python复制import requests
def get_weather(city):
url = f"http://wttr.in/{city}?format=3"
try:
response = requests.get(url, timeout=5)
response.raise_for_status() # 检查HTTP错误
return response.text
except requests.exceptions.RequestException as e:
return f"获取天气失败: {e}"
5.3 添加缓存机制
避免频繁请求同一个城市:
python复制from functools import lru_cache
@lru_cache(maxsize=32)
def get_weather(city):
...
这个装饰器会自动缓存最近32个不同城市的查询结果。
6. 调试与错误处理
6.1 使用pdb调试
在代码中插入断点:
python复制import pdb; pdb.set_trace()
常用命令:
- n(ext): 执行下一行
- c(ontinue): 继续执行
- l(ist): 查看当前代码
- p <变量名>: 打印变量值
6.2 自定义异常
提高错误信息的可读性:
python复制class WeatherError(Exception):
"""自定义天气异常基类"""
pass
class CityNotFoundError(WeatherError):
"""城市不存在异常"""
pass
def get_weather(city):
if not validate_city(city):
raise CityNotFoundError(f"城市{city}不存在")
...
7. 代码质量保障
7.1 单元测试基础
使用unittest模块:
python复制# test_utils.py
import unittest
from utils import get_weather
class TestWeather(unittest.TestCase):
def test_known_city(self):
result = get_weather("Beijing")
self.assertIn("Beijing", result)
def test_unknown_city(self):
with self.assertRaises(CityNotFoundError):
get_weather("NonexistentCity")
if __name__ == '__main__':
unittest.main()
7.2 代码风格检查
安装flake8:
bash复制pip install flake8
运行检查:
bash复制flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
重点关注:
- E9: 语法错误
- F63: 比较运算符使用错误
- F7: 格式错误
8. 项目优化方向
当这个小工具运行稳定后,可以考虑:
- 添加GUI界面(Tkinter/PyQt)
- 支持多天预报
- 增加天气预警功能
- 打包成exe可执行文件
但记住Python之禅:"简单优于复杂"。在初期不要过度设计,先让核心功能跑通更重要。
