遵循PEP 8编码规范,编写清晰、可维护的代码。
my_variableMyClassMAX_SIZE# 好的代码风格
class UserManager:
"""用户管理类"""
def __init__(self, database):
self.database = database
self.users = []
def add_user(self, name, email):
"""添加新用户"""
user = {
'name': name,
'email': email,
'created_at': datetime.now()
}
self.users.append(user)
return user
def get_user_by_email(self, email):
"""根据邮箱查找用户"""
for user in self.users:
if user['email'] == email:
return user
return None
# 不好的代码风格
class usermanager:
def __init__(self,db):
self.db=db
self.users=[]
def addUser(self,n,e):
u={'name':n,'email':e}
self.users.append(u)
return u
# 安装代码检查工具
pip install pylint flake8 black
# 使用pylint检查代码
pylint myfile.py
# 使用flake8检查代码
flake8 myfile.py
# 使用black格式化代码
black myfile.py
# 使用isort整理导入
pip install isort
isort myfile.py
为函数、类和模块编写清晰的文档字符串。
def calculate_average(numbers):
"""
计算数字列表的平均值。
Args:
numbers (list): 数字列表
Returns:
float: 平均值
Raises:
ValueError: 如果列表为空
Examples:
>>> calculate_average([1, 2, 3, 4, 5])
3.0
"""
if not numbers:
raise ValueError("列表不能为空")
return sum(numbers) / len(numbers)
class BankAccount:
"""
银行账户类。
Attributes:
owner (str): 账户所有者
balance (float): 账户余额
"""
def __init__(self, owner, initial_balance=0):
"""
初始化银行账户。
Args:
owner (str): 账户所有者姓名
initial_balance (float, optional): 初始余额,默认为0
"""
self.owner = owner
self.balance = initial_balance
编写测试确保代码质量和正确性。
import unittest
def add(a, b):
return a + b
def divide(a, b):
if b == 0:
raise ValueError("除数不能为零")
return a / b
class TestMathFunctions(unittest.TestCase):
def test_add(self):
self.assertEqual(add(2, 3), 5)
self.assertEqual(add(-1, 1), 0)
def test_divide(self):
self.assertEqual(divide(10, 2), 5)
self.assertAlmostEqual(divide(10, 3), 3.333, places=3)
def test_divide_by_zero(self):
with self.assertRaises(ValueError):
divide(10, 0)
if __name__ == '__main__':
unittest.main()
# 安装pytest
pip install pytest
# test_math.py
def add(a, b):
return a + b
def test_add():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
def test_add_strings():
assert add("hello", "world") == "helloworld"
# 运行测试
pytest test_math.py
# 显示详细信息
pytest -v test_math.py
# 测试覆盖率
pip install pytest-cov
pytest --cov=mymodule tests/
使用logging模块记录程序运行信息。
import logging
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('app.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
# 使用日志
logger.debug("调试信息")
logger.info("程序启动")
logger.warning("警告信息")
logger.error("错误信息")
logger.critical("严重错误")
# 在函数中使用
def process_data(data):
logger.info(f"开始处理数据,数据量: {len(data)}")
try:
result = perform_operation(data)
logger.info("数据处理成功")
return result
except Exception as e:
logger.error(f"数据处理失败: {e}", exc_info=True)
raise
使用配置文件管理应用设置。
# config.json
{
"database": {
"host": "localhost",
"port": 5432,
"name": "mydb"
},
"api": {
"key": "your-api-key",
"timeout": 30
}
}
# 读取配置
import json
def load_config(config_file='config.json'):
with open(config_file, 'r') as f:
return json.load(f)
config = load_config()
db_host = config['database']['host']
import os
from dotenv import load_dotenv
# 安装python-dotenv
# pip install python-dotenv
# .env文件
# DATABASE_URL=postgresql://localhost/mydb
# API_KEY=your-secret-key
# DEBUG=True
# 加载环境变量
load_dotenv()
DATABASE_URL = os.getenv('DATABASE_URL')
API_KEY = os.getenv('API_KEY')
DEBUG = os.getenv('DEBUG', 'False') == 'True'
组织良好的项目结构提高代码可维护性。
myproject/
├── README.md # 项目说明
├── requirements.txt # 依赖列表
├── setup.py # 安装配置
├── .env # 环境变量(不提交到git)
├── .gitignore # Git忽略文件
├── config/ # 配置文件
│ ├── __init__.py
│ └── settings.py
├── src/ # 源代码
│ ├── __init__.py
│ ├── main.py
│ ├── models/
│ │ ├── __init__.py
│ │ └── user.py
│ ├── services/
│ │ ├── __init__.py
│ │ └── user_service.py
│ └── utils/
│ ├── __init__.py
│ └── helpers.py
├── tests/ # 测试代码
│ ├── __init__.py
│ ├── test_models.py
│ └── test_services.py
└── docs/ # 文档
└── api.md
综合运用所学知识,构建一个完整的任务管理系统。
# task.py
from datetime import datetime
from enum import Enum
class TaskStatus(Enum):
TODO = "待办"
IN_PROGRESS = "进行中"
DONE = "已完成"
class TaskPriority(Enum):
LOW = "低"
MEDIUM = "中"
HIGH = "高"
class Task:
def __init__(self, title, description="", priority=TaskPriority.MEDIUM):
self.id = None
self.title = title
self.description = description
self.priority = priority
self.status = TaskStatus.TODO
self.created_at = datetime.now()
self.updated_at = datetime.now()
def to_dict(self):
return {
'id': self.id,
'title': self.title,
'description': self.description,
'priority': self.priority.value,
'status': self.status.value,
'created_at': self.created_at.isoformat(),
'updated_at': self.updated_at.isoformat()
}
@classmethod
def from_dict(cls, data):
task = cls(data['title'], data['description'])
task.id = data['id']
task.priority = TaskPriority(data['priority'])
task.status = TaskStatus(data['status'])
task.created_at = datetime.fromisoformat(data['created_at'])
task.updated_at = datetime.fromisoformat(data['updated_at'])
return task
# task_manager.py
import json
from pathlib import Path
class TaskManager:
def __init__(self, data_file='tasks.json'):
self.data_file = Path(data_file)
self.tasks = []
self.next_id = 1
self.load_tasks()
def load_tasks(self):
if self.data_file.exists():
with open(self.data_file, 'r', encoding='utf-8') as f:
data = json.load(f)
self.tasks = [Task.from_dict(t) for t in data]
if self.tasks:
self.next_id = max(t.id for t in self.tasks) + 1
def save_tasks(self):
with open(self.data_file, 'w', encoding='utf-8') as f:
data = [t.to_dict() for t in self.tasks]
json.dump(data, f, ensure_ascii=False, indent=2)
def add_task(self, title, description="", priority=TaskPriority.MEDIUM):
task = Task(title, description, priority)
task.id = self.next_id
self.next_id += 1
self.tasks.append(task)
self.save_tasks()
return task
def get_task(self, task_id):
for task in self.tasks:
if task.id == task_id:
return task
return None
def update_task(self, task_id, **kwargs):
task = self.get_task(task_id)
if task:
for key, value in kwargs.items():
if hasattr(task, key):
setattr(task, key, value)
task.updated_at = datetime.now()
self.save_tasks()
return task
return None
def delete_task(self, task_id):
task = self.get_task(task_id)
if task:
self.tasks.remove(task)
self.save_tasks()
return True
return False
def list_tasks(self, status=None):
if status:
return [t for t in self.tasks if t.status == status]
return self.tasks
# main.py
def main():
manager = TaskManager()
while True:
print("\n=== 任务管理系统 ===")
print("1. 添加任务")
print("2. 查看所有任务")
print("3. 更新任务状态")
print("4. 删除任务")
print("5. 退出")
choice = input("\n请选择操作: ")
if choice == '1':
title = input("任务标题: ")
description = input("任务描述: ")
task = manager.add_task(title, description)
print(f"任务创建成功!ID: {task.id}")
elif choice == '2':
tasks = manager.list_tasks()
if not tasks:
print("暂无任务")
else:
for task in tasks:
print(f"[{task.id}] {task.title} - {task.status.value}")
elif choice == '3':
task_id = int(input("任务ID: "))
print("1. 待办 2. 进行中 3. 已完成")
status_choice = input("选择状态: ")
status_map = {
'1': TaskStatus.TODO,
'2': TaskStatus.IN_PROGRESS,
'3': TaskStatus.DONE
}
if status_choice in status_map:
manager.update_task(task_id, status=status_map[status_choice])
print("状态更新成功!")
elif choice == '4':
task_id = int(input("任务ID: "))
if manager.delete_task(task_id):
print("任务删除成功!")
else:
print("任务不存在")
elif choice == '5':
print("再见!")
break
if __name__ == '__main__':
main()
恭喜你完成了Python学习之旅!你已经掌握了: