当前位置:首页>python>第4.3章:快速学习Python的数据类与类型系统

第4.3章:快速学习Python的数据类与类型系统

  • 2026-08-20 21:51:46
第4.3章:快速学习Python的数据类与类型系统

《Python AI 应用开发入门》第 4.3 节。

使用 dataclass 建立消息、用户和模型响应,并用可选、联合与容器类型表达数据结构。

本节目标

学完本节后,你应当能够:

  1. 1. 判断一个类是否适合写成数据类。
  2. 2. 使用 @dataclass 定义数据模型。
  3. 3. 理解数据类自动生成的初始化、显示和比较行为。
  4. 4. 为字段设置普通默认值和 default_factory
  5. 5. 使用 __post_init__ 完成简单运行时验证。
  6. 6. 使用 T | NoneOptional[T] 和联合类型。
  7. 7. 为列表、字典和元组添加容器类型注解。
  8. 8. 区分“说明预期类型”和“检查实际数据”。
  9. 9. 在数据类、普通类和字典之间做出选择。

1. 为什么需要数据类

上一节使用普通类组织状态和行为。但有些类的任务很简单:只需要清楚地保存一组数据。

例如,一条消息包含角色和内容。使用普通类可以这样写:

class Message:    def __init__(self, role, content):        self.role = role        self.content = content

这段代码没有问题。不过随着数据模型增多,我们会反复编写相似的初始化代码。为了方便调试和测试,通常还希望这些对象能够:

  • • 打印时显示字段内容。
  • • 能判断两条数据是否相等。
  • • 清楚声明每个字段的类型。

数据类就是为这种场景准备的:我们声明“有哪些字段”,Python 帮我们生成初始化、显示和比较等常用代码。

2. 第一个数据类

dataclass 来自 Python 标准库:

from dataclasses import dataclass@dataclassclass Message:    role: str    content: str

创建对象:

message = Message(    role="user",    content="什么是数据类?",)print(message.role)print(message.content)print(message)

输出类似:

user什么是数据类?Message(role='user', content='什么是数据类?')

类体中的两行代码分别声明了字段名和预期类型:

  • • role: strrole 字段预期保存字符串。
  • • content: strcontent 字段预期保存字符串。

@dataclass 会读取这些字段声明,并为紧跟在下面的类生成常用方法。

@... 这种写法叫装饰器语法。当前先理解为“让 dataclass 帮这个类生成数据模型常用代码”,下一节会解释装饰器的基本原理。

3. @dataclass 帮我们生成了什么

默认情况下,@dataclass 会根据字段生成几个常用方法。

初始化方法

前面的 Message 大致获得了下面这个初始化方法:

def __init__(self, role: str, content: str):    self.role = role    self.content = content

因此我们不用自己编写 __init__()。创建对象时可以使用位置参数,也可以使用关键字参数;字段较多时,关键字参数通常更容易读懂。

可读的对象表示

普通对象直接打印时,通常只会看到类名和内存地址。数据类生成了更清楚的对象表示,因此 print(message) 会直接显示类名和各个字段,调试时更容易看出对象里保存了什么。

按字段比较

first = Message("user", "你好")second = Message("user", "你好")print(first == second)  # Trueprint(first is second)  # False

两个变量虽然指向不同对象,但字段值相同,所以 == 得到 Trueis 判断的是“是否就是同一个对象”,因此得到 False

数据类不会替你自动完成业务验证、JSON 转换或文件保存,这些职责仍需显式设计。

4. 字段默认值

字段也可以提供默认值。下面创建 ModelResponse 时,只需要传入 content,其余字段会使用默认值:

from dataclasses import dataclass@dataclassclass ModelResponse:    content: str    model: str = "demo-model"    finish_reason: str | None = None

使用:

response = ModelResponse(content="这是一条模拟回答。")print(response.model)          # demo-modelprint(response.finish_reason)  # None

str | None 表示字段可以是字符串,也可以是 None。本节后面会详细解释。

和函数参数一样,没有默认值的字段要写在前面,有默认值的字段写在后面。否则 Python 无法生成合法的 __init__() 参数顺序。

5. 为什么列表字段要使用 default_factory

会话对象通常需要一个默认的空消息列表。最直观的写法似乎是直接把 [] 作为默认值:

from dataclasses import dataclass@dataclassclass ChatSession:    title: str    messages: list[Message] = []

但是运行到类定义时,Python 会直接报错:

ValueError: mutable default <class 'list'> for field messages is not allowed: use default_factory

此时还没有创建任何 ChatSession 对象。报错发生在 @dataclass 处理类、准备生成 __init__() 的时候。

为什么数据类要拒绝这个写法?因为 [] 会在执行类定义时创建一次,而不是每次创建 ChatSession 时都重新创建。如果允许它作为默认值,生成的 __init__() 就会反复使用同一个列表。结果会是:向第一个会话添加消息,第二个会话也能看到这条消息。

列表可以在创建后继续添加、删除或修改元素,因此属于可变对象。数据类会主动拒绝列表这类可变默认值,避免不同实例意外共享同一份数据。

我们真正需要的是:每创建一个会话,就创建一个新的空列表。这正是 default_factory 解决的问题。

使用 field(default_factory=list)

from dataclasses import dataclass, field@dataclassclass ChatSession:    title: str    messages: list[Message] = field(default_factory=list)

default_factory 可以理解为“默认值生成器”。这里传入的是 list 函数本身,而不是提前创建好的列表。每次创建 ChatSession 时,数据类都会调用一次 list(),所以每个会话都能得到自己的新列表:

first = ChatSession("Python")second = ChatSession("AI")first.messages.append(Message("user", "你好"))print(len(first.messages))   # 1print(len(second.messages))  # 0

注意这里写的是 list,没有括号。如果写成 list(),传入的就不再是“之后用来创建默认值的函数”,而是一个已经创建好的列表。

需要默认字典或集合时,同样把对应的创建函数交给 default_factory

field(default_factory=dict)field(default_factory=set)

它与函数参数中使用 None 避免共享可变默认值解决的是同一类问题:每次创建对象时,都应该得到一份独立的数据。

6. post_init 与运行时验证

数据类替我们生成了 __init__(),但有时保存字段后还要做清理和验证。为此,可以定义 __post_init__()

from dataclasses import dataclass@dataclassclass Message:    role: str    content: str    def __post_init__(self):        self.role = self.role.strip().lower()        self.content = self.content.strip()        if self.role not in ("system", "user", "assistant"):            raise ValueError(f"消息角色无效:{self.role}")        if not self.content:            raise ValueError("消息内容不能为空")

创建对象时的顺序是:先由生成的 __init__() 保存字段,再自动调用 __post_init__()。因此下面传入的多余空格和大写角色会被统一整理:

message = Message(" USER ", " 你好 ")print(message.role)     # userprint(message.content)  # 你好

如果角色无效或内容清理后为空,对象会在创建时立即报错:

# Message("unknown", "你好")# Message("user", "   ")

__post_init__() 适合处理字段自身的简单规则,例如去掉空格、统一大小写和检查取值范围。读取文件、请求网络等复杂操作不适合藏在对象初始化过程中,否则一次看似普通的对象创建会产生难以预料的额外行为。

7. 类型注解是在说明预期,不是在检查数据

下面的字段写了 str

@dataclassclass User:    user_id: str    display_name: str

这里的 str 主要是在告诉读者和开发工具“这个字段预期是字符串”。它可以提供:

  • • 给读者的接口说明。
  • • 编辑器补全与静态检查信息。
  • • 后续类型检查工具可以分析的依据。

但 Python 在运行代码时,默认不会逐项执行这些注解。即使传入整数,下面这行代码仍然可以创建对象:

user = User(user_id=123, display_name="小林")

这不代表整数是正确的数据,只代表类型注解本身不是验证器。如果数据来自 JSON、用户输入或外部 API,还要在运行时检查实际值:

def create_user(value):    if not isinstance(value, dict):        raise ValueError("用户数据必须是字典")    user_id = value.get("user_id")    display_name = value.get("display_name")    if not isinstance(user_id, str) or not user_id.strip():        raise ValueError("user_id 必须是非空字符串")    if not isinstance(display_name, str) or not display_name.strip():        raise ValueError("display_name 必须是非空字符串")    return User(user_id.strip(), display_name.strip())

这里的 isinstance(user_id, str) 会在程序运行时判断 user_id 是否真的是字符串。

可以这样区分二者:

类型注解描述开发者的预期,运行时验证负责检查真实外部数据。

8. 值可能为空时:可选类型

有些字段并不是每次都有内容。例如模型调用成功时,没有错误消息;调用失败时,才需要保存错误原因:

@dataclassclass ModelResponse:    content: str    error_message: str | None = None

str | None 表示值可以是 str 或 None

success = ModelResponse(content="回答成功")failure = ModelResponse(    content="",    error_message="模型暂时不可用",)

也可以使用 Optional

from typing import Optionalerror_message: Optional[str] = None

在这里:

Optional[str]

与:

str | None

表达相同含义。本课程使用 Python 3.11 或更高版本时,优先采用更直接的 str | None

注意,“可选类型”说的是值可以为 None,不是说创建对象时一定可以省略这个参数。参数能否省略,取决于字段是否提供了默认值。

9. 值可能属于多种类型时:联合类型

如果请求编号有时来自系统生成的整数,有时来自外部服务的字符串,可以把两种可能都写出来:

request_id: str | int

传统写法是:

from typing import Unionrequest_id: Union[str, int]

两者表达相同含义。

联合类型应该有明确原因。不要为了“什么值都能传”而不断追加类型;可能性越多,使用这个字段的代码就越难处理。

如果一个字段的不同类型代表完全不同状态,通常更适合拆成不同数据模型,或重新设计字段。

10. 说明容器里保存什么

只写 list 或 dict,读者仍然不知道容器里保存的是什么。类型注解可以继续说明内部元素:

messages: list[Message]metadata: dict[str, str]allowed_roles: tuple[str, ...]tags: set[str]

含义分别是:

  • • list[Message]:元素都是 Message 的列表。
  • • dict[str, str]:键和值都是字符串的字典。
  • • tuple[str, ...]:包含任意数量字符串的元组。
  • • set[str]:元素都是字符串的集合。

固定长度且每个位置类型不同的元组可以写成:

result: tuple[str, int]

它表示第一项是字符串,第二项是整数。

嵌套类型要以可读性为限:

history_by_user: dict[str, list[Message]]

如果类型长到很难读,考虑建立新的数据类,而不是继续堆叠容器。

11. 消息、用户与模型响应

from dataclasses import dataclass@dataclassclass User:    user_id: str    display_name: str@dataclassclass Message:    role: str    content: str    def __post_init__(self):        self.role = self.role.strip().lower()        self.content = self.content.strip()        if self.role not in ("system", "user", "assistant"):            raise ValueError("消息角色无效")        if not self.content:            raise ValueError("消息内容不能为空")@dataclassclass ModelResponse:    content: str    model: str    finish_reason: str | None = None    usage_tokens: int | None = None

每个数据类只表达一个清楚的概念。和到处传递字典相比,调用者不必再凭记忆猜测有哪些键,编辑器也能根据字段提供提示。

12. 数据类与 JSON

JSON 模块处理的是字典、列表、字符串等基础数据,不能直接识别任意数据类。asdict() 可以先把数据类递归转换为字典:

from dataclasses import asdictmessage = Message("user", "解释数据类")message_data = asdict(message)print(message_data)# {'role': 'user', 'content': '解释数据类'}

转换后的字典可以交给 json.dumps()

import jsontext = json.dumps(    message_data,    ensure_ascii=False,    indent=2,)print(text)

反过来,从 JSON 得到的只是外部字典,内容可能缺失或类型错误。应该先读取和检查字段,再创建数据类:

def message_from_dict(value) -> Message:    if not isinstance(value, dict):        raise ValueError("消息必须是字典")    role = value.get("role")    content = value.get("content")    if not isinstance(role, str):        raise ValueError("role 必须是字符串")    if not isinstance(content, str):        raise ValueError("content 必须是字符串")    return Message(role=role, content=content)

message_from_dict() 先检查外层结构和字段类型,Message.__post_init__() 再检查角色范围和非空内容。两层检查各自负责一部分规则。

13. 数据类中的会话

from dataclasses import dataclass, field@dataclassclass ChatSession:    title: str    messages: list[Message] = field(default_factory=list)    def __post_init__(self):        self.title = self.title.strip()        if not self.title:            raise ValueError("会话标题不能为空")    def add_message(self, message: Message) -> None:        self.messages.append(message)    def recent_messages(self, limit: int = 5) -> list[Message]:        if limit <= 0:            raise ValueError("limit 必须大于 0")        return self.messages[-limit:].copy()

使用:

session = ChatSession("数据类练习")session.add_message(Message("user", "什么是 default_factory?"))print(session.recent_messages())

数据类并不等于“只能放字段、不能写方法”。ChatSession 的主体仍是一组明确的会话数据,add_message() 和 recent_messages() 又紧密围绕这些数据工作,因此使用数据类仍然合理。

14. 该选数据类、普通类还是字典

方案
适合场景
字典
数据结构暂时不固定,或刚从 JSON 读取、尚未验证
数据类
字段固定清楚,主要任务是表示一组相关数据
普通类
主要任务是执行操作、协调其他对象,或初始化过程较复杂

可以先问自己:“这个对象最主要是在表示数据,还是在完成任务?”在本章项目中:

  • • MessageUserModelResponse:数据类。
  • • ChatSession:数据类或普通类都可以,取决于封装要求。
  • • ModelClientChatService:普通类,因为主要职责是行为和协作。
  • • JSON 刚解析出来的内容:先保留为字典,验证通过后再转换成数据类。

常见错误

把类型注解当成验证器

Python 默认不会仅靠 content: str 拒绝整数。外部数据仍需 isinstance() 或明确构造函数验证。

使用共享可变默认值

列表、字典和集合字段使用 field(default_factory=...),不要为所有实例共享同一个对象。

把所有类都改成数据类

模型客户端的核心是行为,不需要为了统一形式强行使用 @dataclass

创建过于复杂的联合类型

如果调用者需要大量 isinstance() 才能判断字段含义,优先重新设计数据模型。

动手练习

练习 1:消息模型

定义 Message 数据类,包含 role 和 content。使用 __post_init__ 清理并验证数据,测试三个有效角色、空内容和无效角色。

练习 2:响应模型

定义 ModelResponse

  • • content: str
  • • model: str
  • • finish_reason: str | None = None
  • • usage_tokens: int | None = None

创建成功与失败示例,并解释每个可选字段。

练习 3:会话与 JSON

定义使用 default_factory=list 的 ChatSession,加入两条 Message,使用 asdict() 和 json.dumps() 导出。再编写 message_from_dict() 恢复并验证消息。

随堂小测

  1. 1. 数据类主要减少哪些重复代码?
  2. 2. @dataclass 如何知道哪些名字是字段?
  3. 3. 为什么列表字段要使用 default_factory
  4. 4. __post_init__ 在什么时候执行?
  5. 5. str | None 表示什么?
  6. 6. Optional[str] 是否表示函数参数可以省略?
  7. 7. list[Message] 提供了什么信息?
  8. 8. 为什么从 JSON 恢复数据类前仍需验证?
  9. 9. == 与 is 比较数据类时有什么区别?

参考答案

  1. 1. 常见的初始化、对象显示和按字段比较代码。
  2. 2. 根据类体中带类型注解的字段定义。
  3. 3. 保证每个实例调用工厂函数,获得独立的新列表。
  4. 4. 数据类生成的初始化方法保存字段之后自动执行。
  5. 5. 值可以是字符串或 None
  6. 6. 不是;参数能否省略由是否提供默认值决定。
  7. 7. 说明这是一个元素预期为 Message 的列表,帮助读者、编辑器和类型检查工具。
  8. 8. 类型注解不会自动保证运行时数据正确,外部数据可能缺字段、类型错误或违反业务规则。
  9. 9. == 比较字段值,is 判断是否为同一个对象。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-21 15:47:47 HTTP/2.0 GET : https://f.mffb.com.cn/a/511057.html
  2. 运行时间 : 0.275438s [ 吞吐率:3.63req/s ] 内存消耗:4,605.38kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=33c0acba03ead786aaf7b7c1f630f660
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000938s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001704s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000726s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.005074s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001708s ]
  6. SELECT * FROM `set` [ RunTime:0.018322s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001878s ]
  8. SELECT * FROM `article` WHERE `id` = 511057 LIMIT 1 [ RunTime:0.004654s ]
  9. UPDATE `article` SET `lasttime` = 1787298467 WHERE `id` = 511057 [ RunTime:0.036942s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000685s ]
  11. SELECT * FROM `article` WHERE `id` < 511057 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001201s ]
  12. SELECT * FROM `article` WHERE `id` > 511057 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001082s ]
  13. SELECT * FROM `article` WHERE `id` < 511057 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001970s ]
  14. SELECT * FROM `article` WHERE `id` < 511057 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.006158s ]
  15. SELECT * FROM `article` WHERE `id` < 511057 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.026850s ]
0.279110s