当前位置:首页>python>Python OOP 设计思想 13:封装服务于演化

Python OOP 设计思想 13:封装服务于演化

  • 2026-01-20 08:35:31
Python OOP 设计思想 13:封装服务于演化

在许多面向对象讨论中,封装常被解释为“隐藏实现细节”。但在 Python 的语境中,这种解释并不完整。封装的真正目的不是隐藏,而是为变化提供缓冲空间。

13.1 封装与变化的关系

如果一个系统从不变化,封装几乎没有价值。封装存在的根本原因,是软件不可避免地要演化。

在 Python 中,封装并不等同于“禁止访问”。

下划线命名(如 _storage)只是约定,而非屏障。真正的封装关注的是:哪些使用方式被鼓励,哪些变化被允许延迟。

因此,判断封装是否成功,不能看属性是否可见,而要看调用方是否被迫依赖内部结构。

# 未考虑变化的封装class User:    def __init__(self, name, email):        self.name = name        self.email = email        self._storage = {}  # 内部数据结构直接暴露    def save(self):        # 直接将内部数据保存        self._storage["name"] = self.name        self._storage["email"] = self.email        return self._storage# 调用方依赖内部结构user = User("艾婉婷""xiaoai@example.com")data = user.save()print(data["name"])  # 直接访问内部数据结构

该示例的问题不在于“属性是否以下划线开头”,而在于 save() 的返回值暴露了内部数据结构,使调用方获得了不该拥有的结构性知识。

一旦调用方开始依赖这些细节,任何内部调整都会被放大为破坏性变更。

没有变化缓冲的封装,本质上并未真正封装。

在 Python 中,封装并不主要体现在“谁能访问谁”,而体现在:

• 哪些使用方式被允许

• 哪些行为被视为稳定承诺

• 哪些细节可以在不破坏调用方的前提下被替换

因此,封装不是为当前代码服务,而是为未来变化预留回旋余地。

13.2 可替换实现的边界

一个良好封装的设计,应当明确回答一个问题:在不修改调用方的前提下,哪些部分可以被替换?

封装的边界,决定了系统中哪些部分可以被独立替换。

在 Python 中,这种边界通常不是由 private 关键字划定,而是由稳定的方法名、参数语义与返回约定共同形成

只要调用方只依赖这些稳定承诺,实现就可以被自由替换。

# 良好封装的示例:可替换实现class DataStore:    """稳定的接口:只承诺读写能力"""    def save(self, key, value):        """保存数据,具体实现可替换"""        raise NotImplementedError    def load(self, key):        """加载数据,具体实现可替换"""        raise NotImplementedErrorclass FileDataStore(DataStore):    """文件存储实现"""    def save(self, key, value):        with open(f"{key}.txt""w"as f:            f.write(str(value))    def load(self, key):        with open(f"{key}.txt"as f:            return f.read()class MemoryDataStore(DataStore):    """内存存储实现"""    def __init__(self):        self._data = {}    def save(self, key, value):        self._data[key] = value    def load(self, key):        return self._data.get(key)# 调用方只依赖稳定接口def process_data(store: DataStore, data):    """可以在不修改调用方的情况下替换 store 实现"""    store.save("result", data)    return store.load("result")# 可以轻松切换实现file_store = FileDataStore()memory_store = MemoryDataStore()process_data(file_store, "file data")     # 使用文件存储process_data(memory_store, "mem data")    # 切换到内存存储

在 DataStore 示例中,封装的核心并不是抽象类本身,而是调用方只关心“保存”和“读取”的行为语义。

文件存储与内存存储的差异,被成功限制在实现内部。

这种封装并不减少功能,而是延迟了变化的传播范围,这是封装对演化最直接的价值。

在 Python 中,封装边界通过以下方式体现:

• 稳定的方法名与调用语义

• 清晰的返回值与异常约定

• 明确的副作用边界

13.3 演化中的接口稳定

接口稳定性并不意味着接口“永远不改”,而意味着:既有调用方式的语义不会被破坏。

在 Python 中,演进式接口往往通过“参数扩展”、“默认值”、“新增私有方法”完成,而非推翻既有方法签名。

# 接口的演进示例class StorageV1:    def save(self, data):        return self._save_to_file(data)    def _save_to_file(self, data):        return f"saved:{data}"class StorageV2(StorageV1):    """演进版本:扩展功能但不破坏原有接口"""    def save(self, data, compress=False):        """增强版本:支持压缩选项"""        if compress:            data = self._compress(data)        return self._save_to_file(data)    def _compress(self, data):        """新增内部方法,不影响接口"""        return f"compressed:{data}"# 原有调用方继续工作storage = StorageV2()storage.save("data")           # 原有调用方式storage.save("data"True)     # 新增调用方式

StorageV2 的演进方式表明,接口的演化应当是在不破坏既有语义的前提下扩展能力。

新增参数与私有方法并不会影响旧调用方,却为新需求打开空间。

这正是封装在演化中的作用:不是阻止变化,而是让变化以可控方式发生。

在 Python 项目中,封装良好的接口通常具备以下特征:

• 调用点集中

• 行为语义清晰

• 失败路径可预期

当接口需要演化时,封装的作用在于延迟破坏性变更的到来,而非阻止变化本身。

13.4 封装失败的常见模式

封装失败,往往不是因为“暴露得太多”,而是因为封装了不该封装的东西。

当一个接口尚未稳定、变化方向尚不明确时,过早将其封装为“可复用组件”,反而会放大未来的修改成本。

在 Python 中,真正危险的并不是访问权限,而是调用方被迫理解并依赖内部决策逻辑。

# 封装失败的模式class ConfigManager:    def __init__(self):        # 问题 1:使用单个下划线,暗示"受保护"但实际上仍然公开        self._settings = {}    # 调用方可能直接修改        self._cache = []       # 内部实现细节暴露    # 允许直接访问内部数据    def get_raw_settings(self):        return self._settings    # 问题 2:返回内部可变对象的引用    # 调用方需要知道内部结构才能使用    def update_setting(self, key, value):        self._settings[key] = value        self._cache.clear()    # 问题 3:调用方不知道这个副作用# 更好的封装class ConfigManager2:    def __init__(self):        # 正确:使用双下划线前缀实现名称改写        self.__settings = {}        self.__cache = []    # 内部细节完全隐藏    def get_setting(self, key):        """稳定接口:返回值的副本"""        return self.__settings.get(key)    # 正确:返回数据的副本或不可变值,而不是引用    def update_setting(self, key, value):        """        正确:明确的接口,清晰的副作用        提供完整的操作语义:        1. 更新设置        2. 清空缓存(副作用在文档中说明)        3. 返回旧值(完整的事务语义)        """        old = self.__settings.get(key)        self.__settings[key] = value        self.__cache.clear()    # 副作用在方法名或文档中应明确说明        return old    # 明确返回旧值,提供完整信息

ConfigManager 的问题并不在于 _settings 和 _cache 的存在,而在于它们被间接暴露为“可依赖事实”。

一旦调用方拿到可变的内部结构,封装边界便已经失守:内部缓存策略、数据结构乃至一致性规则,都被泄漏为系统外部的隐性约束。

ConfigManager2 的改进并不是“更私有”,而是更明确:哪些行为是稳定承诺,哪些副作用是必然结果,都通过接口语义显式表达。

这说明,封装失败的本质,是变化被错误地分配给了调用方。

常见封装失败模式包括:

• 将内部数据结构直接暴露给外部

• 让调用方依赖实现细节而非行为语义

• 过度封装尚未稳定的抽象

正确封装的原则是:告诉使用者要做什么,而不是怎么做。

13.5 为未来变化预留空间

为变化预留空间,并不是试图提前设计所有可能的功能,而是避免把当前实现细节误当成长期承诺。

Python 中常见的做法是:对外接口保持最小而稳定,对内实现允许不确定性存在。

# 为变化预留空间的封装class PaymentProcessor:    """最小化接口:为演化预留空间"""    def process(self, amount, **options):        """        处理支付        Args:            amount: 金额            **options: 未来扩展参数        Returns:            支付结果        """        # 保持核心语义稳定        result = self._do_process(amount, options)        return self._format_result(result)    def _do_process(self, amount, options):        """可替换的实现细节"""        # 当前实现        return {"status""success""amount": amount}    def _format_result(self, raw_result):        """可调整的输出格式化"""        return raw_result  # 目前原样返回,未来可调整# 未来扩展时不破坏接口class EnhancedPaymentProcessor(PaymentProcessor):    def _do_process(self, amount, options):        # 增强处理逻辑但不改变接口        if options.get("currency") == "USD":            amount = amount * 0.85  # 汇率转换        return {"status""success""amount": amount, "currency": options.get("currency""CNY")}

PaymentProcessor 中的封装策略并未提前定义所有支付规则,而是明确哪些行为是稳定承诺,哪些属于实现自由。

这种设计允许未来通过子类或内部重写引入新逻辑,而无需修改调用方。

封装在这里的意义,是将“不确定性”留在系统内部,而非扩散到使用者一侧。

为变化预留空间的原则:

• 封装稳定的使用方式,而非当前实现

• 允许内部自由变化,但保持外部语义一致

• 用最小接口表达最大行为承诺

13.6 封装的演进策略

在 Python 实践中,封装很少在一开始就“到位”。

更常见的情况是,系统随着需求增长,不断暴露新的变化点,封装策略也随之调整。

因此,讨论封装时,不应问“是否封装得足够彻底”,而应问:当前阶段的封装,是否恰当地承载了当前阶段的变化压力。

示例:封装的渐进演进

# 阶段 1:简单功能,轻量封装def calculate_total(prices):    """简单函数,最小封装"""    return sum(prices)# 阶段 2:功能扩展,引入类封装class OrderCalculator:    """类封装:支持更多功能"""    def calculate_total(self, prices, discount=0):        total = sum(prices)        return total * (1 - discount/100)    def calculate_tax(self, total, tax_rate):        return total * tax_rate# 阶段 3:复杂业务,完整封装class OrderProcessor:    """完整封装:隐藏所有实现细节"""    def __init__(self, tax_calculator, discount_strategy):        self.tax_calc = tax_calculator        self.discount = discount_strategy    def process(self, order):        # 完全封装计算逻辑        subtotal = self._calculate_subtotal(order.items)        discount = self.discount.apply(subtotal, order.customer)        total = subtotal - discount        tax = self.tax_calc.calculate(total, order.region)        return total + tax    def _calculate_subtotal(self, items):        """私有方法:实现细节完全隐藏"""        return sum(item.price * item.quantity for item in items)

从函数到类,再到完整对象协作,这一演进并非“复杂化”,而是变化逐渐显形的结果。

在早期,变化尚少,函数级封装已足够;当折扣、税率、地区规则开始分化,类的职责自然浮现;当变化来源增多且相互独立时,完整封装才成为必要。

这一过程说明,封装不是提前规划好的终点,而是被变化一步步推出来的边界。

好的封装策略,应当允许这种渐进演化,而非强迫系统一次性承担所有抽象成本。

13.7 单一职责原则(SRP)在 Python 中的实践

单一职责原则(Single Responsibility Principle,SRP)强调:一个模块或类应当只有一个引起其变化的原因。

在 Python 中,SRP 并不表现为严格的职责切割或复杂的类型层级,而更多体现在:封装是否将变化源隔离在恰当的位置。

一个违反 SRP 的典型例子是,将多种变化原因封装进同一个对象:

class ReportService:    def generate(self, data):        report = self._format(data)     # 格式变化        self._save_to_file(report)      # 存储变化        self._send_email(report)        # 传输变化

在这里,格式、存储、传输的变化都会迫使 ReportService 修改,封装反而放大了变化影响。

遵循 SRP 的 Python 实践,通常是将变化点拆分为可组合的角色(关注点)分离。每个类只负责一个特定职责,通过组合而非继承构建复杂功能。

class ReportFormatter:    """职责 1:报告格式化 - 只负责数据格式转换"""    def format(self, data):        # 单一职责:将数据转换为报告格式        # 变化点:格式可能变化(HTML/JSON/PDF),但职责不变        return f"REPORT:{data}"class ReportRepository:    """职责 2:报告持久化 - 只负责数据存储"""    def save(self, report):        # 单一职责:保存报告到存储介质        # 变化点:存储方式可能变化(文件/数据库/云存储),但职责不变        print("saved:", report)class ReportNotifier:    """职责 3:报告通知 - 只负责发送通知"""    def notify(self, report):        # 单一职责:发送报告通知        # 变化点:通知方式可能变化(邮件/短信/API),但职责不变        print("sent:", report)class ReportService:    """    职责协调者:组合各个单一职责的角色    遵循 SRP 的实践:    1. 自己不实现格式化、存储、通知功能    2. 只负责协调各个单一职责的组件    3. 通过依赖注入获得灵活性    变化点处理:    - 格式变化 → 更换 ReportFormatter    - 存储变化 → 更换 ReportRepository      - 通知变化 → 更换 ReportNotifier    - ReportService 本身不需要修改(符合开闭原则)    """    def __init__(self, formatter, repository, notifier):        # 依赖注入:组合不同的职责角色        self.formatter = formatter      # 格式化职责        self.repository = repository    # 存储职责        self.notifier = notifier        # 通知职责    def generate(self, data):        """        生成报告流程 - 协调各个单一职责的组件        这个方法仍然遵循 SRP:只负责"报告生成流程"这一个职责        具体的格式化、存储、通知工作委托给专门的角色        """        # 委托给格式化角色        report = self.formatter.format(data)        # 委托给存储角色        self.repository.save(report)        # 委托给通知角色        self.notifier.notify(report)

在这种设计中:

• 每个类只因一种变化而修改

• 封装边界与变化来源高度一致

• 行为通过组合协作,而非继承堆叠

这正是 Python 中 SRP 的核心价值:不是让类更小,而是让变化更可控。

当封装与 SRP 协同工作时,系统演化不再依赖“大规模重构”,而是通过局部替换自然推进。

📘 小结

在 Python 中,封装的目的不在于隐藏,而在于管理变化。通过稳定调用语义、隔离变化来源并延迟实现承诺,封装为系统演化提供缓冲空间。良好的封装不冻结设计,而是允许实现在不破坏既有使用方式的前提下持续调整。封装的价值,最终体现在:变化发生时,系统只需局部修改,而非整体重写。

点赞有美意,赞赏是鼓励

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-02-09 02:06:59 HTTP/2.0 GET : https://f.mffb.com.cn/a/462720.html
  2. 运行时间 : 0.306458s [ 吞吐率:3.26req/s ] 内存消耗:4,784.20kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=5a3f3da5943f59d62c57ab667139a80d
  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.001047s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001417s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.018760s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000686s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001449s ]
  6. SELECT * FROM `set` [ RunTime:0.002314s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001490s ]
  8. SELECT * FROM `article` WHERE `id` = 462720 LIMIT 1 [ RunTime:0.007251s ]
  9. UPDATE `article` SET `lasttime` = 1770574019 WHERE `id` = 462720 [ RunTime:0.007376s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000735s ]
  11. SELECT * FROM `article` WHERE `id` < 462720 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001606s ]
  12. SELECT * FROM `article` WHERE `id` > 462720 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.009488s ]
  13. SELECT * FROM `article` WHERE `id` < 462720 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.029616s ]
  14. SELECT * FROM `article` WHERE `id` < 462720 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.007282s ]
  15. SELECT * FROM `article` WHERE `id` < 462720 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.047031s ]
0.310328s