Python 基础课:面向对象、类型提示与 HTTP 请求
学习目标
今天结束后,你能够:
- 理解类和对象的概念
- 定义类、创建实例、使用方法
- 使用继承和多态构建代码结构
- 添加类型提示提高代码可读性
- 使用 dataclass 简化数据类
- 使用 Pydantic 进行数据验证
- 发送 HTTP 请求调用 API
- 从环境变量读取配置
面向对象编程基础
为什么需要面向对象
函数式编程处理简单任务很方便,但当数据和操作复杂时,面向对象能更好地组织代码。
函数式:
# 管理用户
users = []
def add_user(name, email):
users.append({"name": name, "email": email})
def get_user(name):
for user in users:
if user["name"] == name:
return user
面向对象:
class User:
def __init__(self, name, email):
self.name = name
self.email = email
# 数据和操作封装在一起
user = User("Alice", "alice@example.com")
print(user.name)
类和对象
类(Class):模板,定义了对象的属性和方法 对象(Object):类的实例,实际存在的数据
类比:
- 类 = 图纸(建筑设计图)
- 对象 = 建筑物(根据图纸建造的房子)
定义类
基本语法:
class ClassName:
"""类的说明文档"""
def __init__(self, param1, param2):
"""初始化方法(构造函数)"""
self.attr1 = param1
self.attr2 = param2
def method1(self):
"""实例方法"""
return self.attr1
示例:
class Message:
"""消息类"""
def __init__(self, role, content):
self.role = role
self.content = content
def format(self):
"""格式化输出"""
return f"[{self.role}] {self.content}"
def token_count(self):
"""估算 token 数"""
return len(self.content) // 4
# 创建对象
msg = Message("user", "你好")
print(msg.format()) # [user] 你好
print(msg.token_count()) # 0
__init__ 和 self
__init__:初始化方法,创建对象时自动调用
self:指向对象本身,类似其他语言的 this
class AIModel:
def __init__(self, name, temperature=0.7):
self.name = name
self.temperature = temperature
def describe(self):
# self 指向当前对象
return f"模型 {self.name},温度 {self.temperature}"
# 创建对象
model1 = AIModel("gpt-4")
model2 = AIModel("claude-3", 0.9)
print(model1.describe()) # 模型 gpt-4,温度 0.7
print(model2.describe()) # 模型 claude-3,温度 0.9
实例方法、类方法、静态方法
实例方法:最常用,访问实例属性
class Calculator:
def add(self, a, b):
return a + b
类方法:访问类属性,用 @classmethod 装饰
class AIModel:
model_count = 0 # 类属性
def __init__(self, name):
self.name = name
AIModel.model_count += 1
@classmethod
def get_count(cls):
return cls.model_count
# 使用
model1 = AIModel("gpt-4")
model2 = AIModel("claude-3")
print(AIModel.get_count()) # 2
静态方法:不访问类或实例属性,用 @staticmethod 装饰
class TokenUtils:
@staticmethod
def estimate_tokens(text):
return len(text) // 4
@staticmethod
def calculate_cost(tokens, price_per_1k):
return (tokens / 1000) * price_per_1k
# 使用(不需要创建对象)
tokens = TokenUtils.estimate_tokens("Hello World")
cost = TokenUtils.calculate_cost(tokens, 0.03)
AI 场景示例
class ChatMessage:
"""对话消息类"""
def __init__(self, role, content):
self.role = role
self.content = content
def to_dict(self):
"""转为字典(API 格式)"""
return {"role": self.role, "content": self.content}
def token_count(self):
"""估算 token 数"""
return len(self.content) // 4
class ChatSession:
"""对话会话类"""
def __init__(self, system_prompt=""):
self.messages = []
if system_prompt:
self.add_message("system", system_prompt)
def add_message(self, role, content):
"""添加消息"""
msg = ChatMessage(role, content)
self.messages.append(msg)
def get_messages(self):
"""获取所有消息(字典格式)"""
return [msg.to_dict() for msg in self.messages]
def total_tokens(self):
"""计算总 token 数"""
return sum(msg.token_count() for msg in self.messages)
# 使用
session = ChatSession("你是一个Python助手")
session.add_message("user", "什么是类?")
session.add_message("assistant", "类是面向对象编程的基础")
print(f"消息数: {len(session.messages)}")
print(f"总 tokens: {session.total_tokens()}")
print(session.get_messages())
输出:
消息数: 3
总 tokens: 9
[{'role': 'system', 'content': '你是一个Python助手'}, {'role': 'user', 'content': '什么是类?'}, {'role': 'assistant', 'content': '类是面向对象编程的基础'}]
课堂练习
模型配置类
创建一个 AIModelConfig 类,管理模型配置。
参考答案:
class AIModelConfig:
"""AI 模型配置类"""
def __init__(self, model="gpt-3.5-turbo", temperature=0.7, max_tokens=2000):
self.model = model
self.temperature = temperature
self.max_tokens = max_tokens
def validate(self):
"""验证配置"""
if not (0 <= self.temperature <= 2):
return False, "温度必须在 0-2 之间"
if self.max_tokens <= 0:
return False, "max_tokens 必须大于 0"
return True, "配置合法"
def to_dict(self):
"""转为字典"""
return {
"model": self.model,
"temperature": self.temperature,
"max_tokens": self.max_tokens
}
# 测试
config = AIModelConfig("gpt-4", 0.7, 2000)
is_valid, message = config.validate()
print(f"验证结果: {message}")
print(f"配置: {config.to_dict()}")
输出:
验证结果: 配置合法
配置: {'model': 'gpt-4', 'temperature': 0.7, 'max_tokens': 2000}
继承与多态
继承
继承让子类复用父类的代码,实现代码重用。
基本语法:
class Parent:
def method1(self):
return "Parent method"
class Child(Parent): # 继承 Parent
def method2(self):
return "Child method"
# 子类可以使用父类的方法
obj = Child()
print(obj.method1()) # Parent method
print(obj.method2()) # Child method
重写父类方法:
class Animal:
def speak(self):
return "Some sound"
class Dog(Animal):
def speak(self): # 重写父类方法
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
dog = Dog()
cat = Cat()
print(dog.speak()) # Woof!
print(cat.speak()) # Meow!
调用父类方法:
class BaseModel:
def __init__(self, name):
self.name = name
def describe(self):
return f"模型: {self.name}"
class GPTModel(BaseModel):
def __init__(self, name, version):
super().__init__(name) # 调用父类的 __init__
self.version = version
def describe(self):
base_desc = super().describe() # 调用父类的 describe
return f"{base_desc}, 版本: {self.version}"
model = GPTModel("GPT", "4")
print(model.describe()) # 模型: GPT, 版本: 4
AI 场景示例
class BaseMessage:
"""基础消息类"""
def __init__(self, content):
self.content = content
def token_count(self):
return len(self.content) // 4
def to_dict(self):
raise NotImplementedError("子类必须实现 to_dict")
class UserMessage(BaseMessage):
"""用户消息"""
def to_dict(self):
return {"role": "user", "content": self.content}
class AssistantMessage(BaseMessage):
"""助手消息"""
def __init__(self, content, model="gpt-4"):
super().__init__(content)
self.model = model
def to_dict(self):
return {
"role": "assistant",
"content": self.content,
"model": self.model
}
# 使用
user_msg = UserMessage("你好")
assistant_msg = AssistantMessage("你好!", "gpt-4")
print(user_msg.to_dict())
print(assistant_msg.to_dict())
print(f"用户消息 tokens: {user_msg.token_count()}")
封装:私有属性与 @property
封装是面向对象的核心特性,通过隐藏内部实现细节,只暴露必要的接口。
私有属性
Python 中使用下划线前缀表示私有:
_attribute:单下划线,约定为”内部使用”(弱私有)__attribute:双下划线,名称改写机制(强私有)
class APIClient:
def __init__(self, api_key):
self._api_key = api_key # 单下划线:约定为私有
self.__secret = "secret123" # 双下划线:强私有
def get_key_preview(self):
return self._api_key[:10] + "..."
client = APIClient("sk-1234567890abcdefghij")
print(client._api_key) # 可以访问,但不建议
# print(client.__secret) # AttributeError(无法直接访问)
print(client.get_key_preview()) # sk-1234567...
实际开发建议:
- 使用单下划线
_表示私有(Python 社区约定) - 双下划线
__很少使用(除非真的需要防止子类覆盖)
@property 装饰器
@property 将方法转换为属性,提供优雅的访问接口。
基础用法:
class ChatSession:
def __init__(self):
self._messages = []
@property
def message_count(self):
"""消息数量(只读属性)"""
return len(self._messages)
def add_message(self, role, content):
self._messages.append({"role": role, "content": content})
session = ChatSession()
session.add_message("user", "你好")
session.add_message("assistant", "你好!")
print(session.message_count) # 2(像访问属性一样)
# session.message_count = 10 # AttributeError(只读,不能赋值)
getter 和 setter:
class ModelConfig:
def __init__(self, temperature=0.7):
self._temperature = temperature
@property
def temperature(self):
"""获取温度参数"""
return self._temperature
@temperature.setter
def temperature(self, value):
"""设置温度参数(带验证)"""
if not 0 <= value <= 2:
raise ValueError("temperature 必须在 0-2 之间")
self._temperature = value
config = ModelConfig()
print(config.temperature) # 0.7
config.temperature = 0.9 # 通过 setter 设置
print(config.temperature) # 0.9
# config.temperature = 3.0 # ValueError: temperature 必须在 0-2 之间
AI 场景示例
class APIClient:
"""API 客户端"""
def __init__(self, api_key):
self._api_key = api_key
self._request_count = 0
self._total_tokens = 0
@property
def api_key_preview(self):
"""显示 API Key 预览(隐藏真实值)"""
if len(self._api_key) > 10:
return self._api_key[:10] + "..." + self._api_key[-4:]
return "***"
@property
def request_count(self):
"""请求次数(只读)"""
return self._request_count
@property
def total_tokens(self):
"""总 token 数(只读)"""
return self._total_tokens
@property
def average_tokens(self):
"""平均每次请求的 token 数(计算属性)"""
if self._request_count == 0:
return 0
return self._total_tokens / self._request_count
def call_api(self, prompt, tokens_used):
"""调用 API"""
self._request_count += 1
self._total_tokens += tokens_used
return f"Response for: {prompt}"
# 使用
client = APIClient("sk-1234567890abcdefghijklmnop")
print(f"API Key: {client.api_key_preview}") # sk-1234567...mnop
client.call_api("你好", 100)
client.call_api("天气", 150)
print(f"请求次数: {client.request_count}") # 2
print(f"总tokens: {client.total_tokens}") # 250
print(f"平均tokens: {client.average_tokens}") # 125.0
使用场景
1. 只读属性
class Message:
def __init__(self, content):
self._content = content
self._timestamp = datetime.now()
@property
def timestamp(self):
"""时间戳(只读)"""
return self._timestamp
@property
def content_preview(self):
"""内容预览(只读)"""
return self._content[:50] + "..." if len(self._content) > 50 else self._content
2. 计算属性
class TokenCounter:
def __init__(self):
self._input_tokens = 0
self._output_tokens = 0
@property
def total_tokens(self):
"""总 tokens(计算得出)"""
return self._input_tokens + self._output_tokens
@property
def cost(self):
"""费用(根据 tokens 计算)"""
return (self._input_tokens * 0.002 + self._output_tokens * 0.004) / 1000
3. 属性验证
class ChatConfig:
def __init__(self):
self._max_tokens = 2000
@property
def max_tokens(self):
return self._max_tokens
@max_tokens.setter
def max_tokens(self, value):
if not isinstance(value, int):
raise TypeError("max_tokens 必须是整数")
if value <= 0:
raise ValueError("max_tokens 必须大于 0")
if value > 4000:
raise ValueError("max_tokens 不能超过 4000")
self._max_tokens = value
课堂练习
安全的 API 配置类
创建一个配置类,使用私有属性和 @property 保护敏感信息。
参考答案:
from datetime import datetime
class APIConfig:
"""API 配置类"""
def __init__(self, api_key, model="gpt-3.5-turbo"):
self._api_key = api_key
self._model = model
self._created_at = datetime.now()
@property
def api_key_masked(self):
"""返回隐藏的 API Key"""
return "*" * (len(self._api_key) - 4) + self._api_key[-4:]
@property
def model(self):
"""模型名称"""
return self._model
@model.setter
def model(self, value):
"""设置模型(带验证)"""
allowed_models = ["gpt-3.5-turbo", "gpt-4", "claude-3"]
if value not in allowed_models:
raise ValueError(f"不支持的模型: {value}")
self._model = value
@property
def age_seconds(self):
"""配置存在时长(秒)"""
return (datetime.now() - self._created_at).total_seconds()
# 测试
config = APIConfig("sk-1234567890")
print(f"API Key: {config.api_key_masked}") # **********7890
print(f"模型: {config.model}") # gpt-3.5-turbo
config.model = "gpt-4"
print(f"新模型: {config.model}") # gpt-4
# config.model = "unknown" # ValueError: 不支持的模型
类型提示
类型提示让代码更易读、易维护,IDE 能提供更好的代码补全。
基础类型提示
def greet(name: str) -> str:
return f"Hello, {name}!"
def add(a: int, b: int) -> int:
return a + b
# 变量类型提示
age: int = 25
name: str = "Alice"
is_active: bool = True
复杂类型提示
from typing import List, Dict, Optional, Union
# 列表
def process_messages(messages: List[str]) -> int:
return len(messages)
# 字典
def get_config() -> Dict[str, any]:
return {"model": "gpt-4", "temperature": 0.7}
# 可选值
def find_user(name: str) -> Optional[Dict]:
# 可能返回字典或 None
return {"name": name} if name else None
# 多种类型
def format_value(value: Union[int, str, float]) -> str:
return str(value)
AI 场景示例
from typing import List, Dict, Optional
class ChatAPI:
"""对话 API 类"""
def __init__(self, api_key: str, model: str = "gpt-3.5-turbo"):
self.api_key: str = api_key
self.model: str = model
def send_message(
self,
messages: List[Dict[str, str]],
temperature: float = 0.7,
max_tokens: int = 2000
) -> Optional[str]:
"""发送消息(模拟)"""
if not messages:
return None
# 模拟 API 调用
return "这是 AI 的回复"
def count_tokens(self, text: str) -> int:
"""计算 token 数"""
return len(text) // 4
# 使用
api = ChatAPI("sk-xxx", "gpt-4")
messages = [
{"role": "user", "content": "你好"}
]
response = api.send_message(messages)
print(response)
dataclass
dataclass 是 Python 3.7+ 的特性,简化数据类的定义。
基本用法
传统方式:
class Message:
def __init__(self, role, content):
self.role = role
self.content = content
def __repr__(self):
return f"Message(role={self.role}, content={self.content})"
使用 dataclass:
from dataclasses import dataclass
@dataclass
class Message:
role: str
content: str
# 自动生成 __init__、__repr__ 等方法
msg = Message("user", "你好")
print(msg) # Message(role='user', content='你好')
默认值和字段
from dataclasses import dataclass, field
from typing import List
@dataclass
class ModelConfig:
model: str = "gpt-3.5-turbo"
temperature: float = 0.7
max_tokens: int = 2000
tags: List[str] = field(default_factory=list) # 可变默认值
config = ModelConfig()
print(config)
AI 场景示例
from dataclasses import dataclass
from typing import List, Optional
@dataclass
class ChatMessage:
role: str
content: str
def token_count(self) -> int:
return len(self.content) // 4
@dataclass
class ChatRequest:
model: str
messages: List[ChatMessage]
temperature: float = 0.7
max_tokens: int = 2000
stream: bool = False
@dataclass
class ChatResponse:
content: str
model: str
tokens_used: int
cost: float
# 使用
msg1 = ChatMessage("user", "你好")
msg2 = ChatMessage("assistant", "你好!")
request = ChatRequest(
model="gpt-4",
messages=[msg1, msg2]
)
print(request)
Pydantic
Pydantic 是强大的数据验证库,常用于 API 开发和配置管理。
安装
pip install pydantic
基本用法
from pydantic import BaseModel, Field
class User(BaseModel):
name: str
age: int
email: str
# 自动验证类型
user = User(name="Alice", age=25, email="alice@example.com")
print(user)
print(user.model_dump()) # 转为字典
# 类型错误会抛出异常
try:
invalid_user = User(name="Bob", age="not a number", email="bob@example.com")
except Exception as e:
print(f"验证失败: {e}")
字段验证
from pydantic import BaseModel, Field
class ModelConfig(BaseModel):
model: str = Field(..., description="模型名称")
temperature: float = Field(0.7, ge=0, le=2, description="温度参数")
max_tokens: int = Field(2000, gt=0, description="最大 token 数")
class Config:
# 配置
validate_assignment = True # 赋值时也验证
# 使用
config = ModelConfig(model="gpt-4", temperature=0.8)
print(config)
# 尝试设置非法值
try:
config.temperature = 3.0 # 超出范围
except Exception as e:
print(f"验证失败: {e}")
AI 场景示例
from pydantic import BaseModel, Field, validator
from typing import List, Optional
class ChatMessage(BaseModel):
role: str = Field(..., pattern="^(system|user|assistant)$")
content: str = Field(..., min_length=1)
@validator('content')
def content_not_empty(cls, v):
if not v.strip():
raise ValueError('内容不能为空')
return v
class ChatRequest(BaseModel):
model: str = Field(default="gpt-3.5-turbo")
messages: List[ChatMessage] = Field(..., min_items=1)
temperature: float = Field(default=0.7, ge=0, le=2)
max_tokens: int = Field(default=2000, gt=0, le=4000)
stream: bool = False
# 使用
try:
request = ChatRequest(
model="gpt-4",
messages=[
ChatMessage(role="user", content="你好")
],
temperature=0.8
)
print(request.model_dump_json(indent=2))
except Exception as e:
print(f"验证失败: {e}")
HTTP 请求与 API 调用
requests 库
requests 是最常用的 HTTP 库。
安装:
pip install requests
基本用法:
import requests
# GET 请求
response = requests.get("https://api.example.com/users")
print(response.status_code) # 200
print(response.json()) # 解析 JSON
# POST 请求
data = {"name": "Alice", "email": "alice@example.com"}
response = requests.post("https://api.example.com/users", json=data)
print(response.json())
# 带请求头
headers = {"Authorization": "Bearer xxx"}
response = requests.get("https://api.example.com/protected", headers=headers)
异常处理
import requests
try:
response = requests.get("https://api.example.com/data", timeout=5)
response.raise_for_status() # 状态码非 2xx 抛出异常
data = response.json()
print(data)
except requests.Timeout:
print("请求超时")
except requests.HTTPError as e:
print(f"HTTP 错误: {e}")
except requests.RequestException as e:
print(f"请求失败: {e}")
AI API 调用示例
import requests
import os
from typing import List, Dict, Optional
class OpenAIClient:
"""OpenAI API 客户端"""
def __init__(self, api_key: Optional[str] = None):
self.api_key = api_key or os.getenv("OPENAI_API_KEY")
self.base_url = "https://api.openai.com/v1"
def chat_completion(
self,
messages: List[Dict[str, str]],
model: str = "gpt-3.5-turbo",
temperature: float = 0.7
) -> Optional[str]:
"""发送对话请求"""
url = f"{self.base_url}/chat/completions"
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
data = {
"model": model,
"messages": messages,
"temperature": temperature
}
try:
response = requests.post(url, headers=headers, json=data, timeout=30)
response.raise_for_status()
result = response.json()
return result["choices"][0]["message"]["content"]
except Exception as e:
print(f"API 调用失败: {e}")
return None
# 使用
client = OpenAIClient(api_key="sk-xxx")
messages = [
{"role": "user", "content": "什么是 Python?"}
]
response = client.chat_completion(messages)
if response:
print(response)
环境变量
环境变量用于存储敏感信息(如 API Key),避免硬编码。
使用 os.getenv
import os
# 读取环境变量
api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
print("API Key 未设置")
else:
print(f"API Key: {api_key[:10]}...") # 只显示前10位
使用 python-dotenv
python-dotenv 从 .env 文件加载环境变量。
安装:
pip install python-dotenv
创建 .env 文件:
OPENAI_API_KEY=sk-xxxxxxxxxxxx
MODEL=gpt-4
TEMPERATURE=0.7
加载环境变量:
from dotenv import load_dotenv
import os
# 加载 .env 文件
load_dotenv()
# 读取环境变量
api_key = os.getenv("OPENAI_API_KEY")
model = os.getenv("MODEL", "gpt-3.5-turbo") # 提供默认值
temperature = float(os.getenv("TEMPERATURE", "0.7"))
print(f"模型: {model}")
print(f"温度: {temperature}")
AI 场景示例
from dotenv import load_dotenv
import os
from pydantic import BaseModel, Field
# 加载环境变量
load_dotenv()
class AppConfig(BaseModel):
"""应用配置"""
api_key: str = Field(default_factory=lambda: os.getenv("OPENAI_API_KEY", ""))
model: str = Field(default_factory=lambda: os.getenv("MODEL", "gpt-3.5-turbo"))
temperature: float = Field(default_factory=lambda: float(os.getenv("TEMPERATURE", "0.7")))
max_tokens: int = Field(default_factory=lambda: int(os.getenv("MAX_TOKENS", "2000")))
def validate(self) -> bool:
"""验证配置"""
if not self.api_key:
print("错误: API Key 未设置")
return False
if not (0 <= self.temperature <= 2):
print("错误: 温度参数无效")
return False
return True
# 使用
config = AppConfig()
if config.validate():
print("配置加载成功")
print(f"模型: {config.model}")
else:
print("配置验证失败")
当天作业
AI 对话客户端
创建一个完整的 AI 对话客户端类。
参考答案:
import requests
import os
from dotenv import load_dotenv
from pydantic import BaseModel, Field
from typing import List, Dict, Optional
import json
load_dotenv()
class ChatMessage(BaseModel):
"""对话消息"""
role: str = Field(..., pattern="^(system|user|assistant)$")
content: str
class ChatConfig(BaseModel):
"""对话配置"""
api_key: str = Field(default_factory=lambda: os.getenv("OPENAI_API_KEY", ""))
model: str = "gpt-3.5-turbo"
temperature: float = Field(0.7, ge=0, le=2)
max_tokens: int = Field(2000, gt=0)
class AIChat:
"""AI 对话客户端"""
def __init__(self, config: ChatConfig):
self.config = config
self.messages: List[ChatMessage] = []
self.base_url = "https://api.openai.com/v1"
def add_system_message(self, content: str):
"""添加系统消息"""
msg = ChatMessage(role="system", content=content)
self.messages.append(msg)
def add_user_message(self, content: str):
"""添加用户消息"""
msg = ChatMessage(role="user", content=content)
self.messages.append(msg)
def send(self) -> Optional[str]:
"""发送消息"""
url = f"{self.base_url}/chat/completions"
headers = {
"Authorization": f"Bearer {self.config.api_key}",
"Content-Type": "application/json"
}
data = {
"model": self.config.model,
"messages": [msg.model_dump() for msg in self.messages],
"temperature": self.config.temperature,
"max_tokens": self.config.max_tokens
}
try:
response = requests.post(url, headers=headers, json=data, timeout=30)
response.raise_for_status()
result = response.json()
content = result["choices"][0]["message"]["content"]
# 保存助手回复
assistant_msg = ChatMessage(role="assistant", content=content)
self.messages.append(assistant_msg)
return content
except Exception as e:
print(f"API 调用失败: {e}")
return None
def get_history(self) -> List[Dict]:
"""获取对话历史"""
return [msg.model_dump() for msg in self.messages]
def save_history(self, filename: str):
"""保存对话历史"""
with open(filename, "w", encoding="utf-8") as f:
json.dump(self.get_history(), f, ensure_ascii=False, indent=2)
# 使用
config = ChatConfig(
api_key="sk-xxx",
model="gpt-3.5-turbo",
temperature=0.7
)
chat = AIChat(config)
chat.add_system_message("你是一个Python助手")
chat.add_user_message("什么是类?")
# 发送并获取回复
response = chat.send()
if response:
print(f"AI: {response}")
# 保存历史
chat.save_history("chat_history.json")
今日总结
核心知识点回顾
1. 面向对象
- 类和对象:类是模板,对象是实例
__init__:初始化方法- self:指向对象本身
- 实例方法、类方法、静态方法
2. 继承与多态
- 继承:
class Child(Parent) - 重写方法:子类定义同名方法
- super():调用父类方法
3. 类型提示
- 基础类型:int, str, float, bool
- 复杂类型:List, Dict, Optional, Union
- 函数注解:参数类型和返回值类型
4. dataclass
- @dataclass 装饰器
- 自动生成
__init__、__repr__等 - field():处理可变默认值
5. Pydantic
- BaseModel:数据验证基类
- Field:字段约束
- validator:自定义验证器
- model_dump():转为字典
6. HTTP 请求
- requests.get/post
- headers:请求头
- json:JSON 数据
- raise_for_status():检查状态码
7. 环境变量
- os.getenv():读取环境变量
- python-dotenv:加载 .env 文件
- 避免硬编码敏感信息
Python vs Java 对比
| 特性 | Python | Java |
|---|---|---|
| 类定义 | class Name: | class Name {} |
| 构造函数 | __init__(self, ...) | Name(...) |
| this/self | self(显式) | this(隐式) |
| 继承 | class Child(Parent) | class Child extends Parent |
| 类型提示 | 可选(typing) | 强制 |
| 数据类 | @dataclass | record(Java 14+) |
常见问题
Q:什么时候用函数,什么时候用类? A:数据和操作紧密相关时用类;简单工具函数用函数。
Q:self 是什么? A:指向当前对象的引用,类似 Java 的 this,但必须显式写出。
Q:类型提示是强制的吗? A:不是,Python 运行时不检查类型,但 IDE 和工具会用它提示错误。
Q:Pydantic 和 dataclass 的区别? A:dataclass 只是简化定义,Pydantic 还提供运行时验证。
Q:API Key 应该放哪里? A:.env 文件(不提交到 git)或环境变量,绝不硬编码。
重点注意事项
-
__init__的 self:第一个参数必须是 self -
可变默认值陷阱:
# 错误 def __init__(self, items=[]): self.items = items # 所有实例共享同一个列表 # 正确 def __init__(self, items=None): self.items = items if items else [] -
类型提示不影响运行:写错了不会报错,只是 IDE 提示
-
.env 文件不要提交:添加到 .gitignore
-
API 超时设置:requests 默认无超时,必须设置 timeout