当前位置:首页>python>《Python 从入门到精通》080|面向对象综合案例:用类重构一个真实小项目

《Python 从入门到精通》080|面向对象综合案例:用类重构一个真实小项目

  • 2026-06-27 23:43:41
《Python 从入门到精通》080|面向对象综合案例:用类重构一个真实小项目

天之道,损有余而补不足。人之道,损不足以奉有余。

这句话源自《道德经》第七十七章。老子通过观察自然界和社会现象,提出“天道”与“人道”的对立,强调自然规律的公平性与人类社会的不公。

前面这十章,我们一直在拆着学面向对象。

类和对象是什么class 怎么写 实例属性、实例方法怎么理解__init__ 到底干了什么self 到底是谁 类属性、类方法、静态方法有什么区别 封装为什么重要 继承怎么复用代码 多态为什么能让接口统一

如果这些知识点一直分散着看,很多人会有一种感觉:单独一章我都看懂了,但真到自己写项目,脑子里还是有点散,不知道什么时候该用类,什么时候该加方法,什么时候该继承。

所以这一章,我们不再拆知识点,而是做一个完整的小项目,把这一阶段真正串起来。

这次我们做一个很适合入门、又很贴近真实业务的小系统:

图书借阅管理小项目

这个项目不大,但非常适合用面向对象来重构。因为它里面天然就有很多“角色”:

图书 用户 借阅行为 图书馆

而“角色”这两个字,正是面向对象最擅长处理的东西。

这一章你最重要的目标,不是死记代码,而是感受到一件事:

为什么一个稍微真实一点的项目,用类来组织,真的会比一堆零散变量和函数顺很多。

一、先看不用类时,会写成什么样

假设你想做一个最简单的借阅系统。

如果不用类,很多人第一反应可能会写成这样:

book1_name = 'Python 入门'book1_author = '小王'book1_is_borrowed = Falsebook2_name = '数据分析实战'book2_author = '老李'book2_is_borrowed = Falseuser1_name = '张三'user1_borrowed_books = []

然后借书逻辑再单独写函数:

defborrow_book(user_name, borrowed_books, book_name, book_is_borrowed):if book_is_borrowed:        print(f'{book_name} 已经被借走了')else:        borrowed_books.append(book_name)        print(f'{user_name} 成功借阅了 {book_name}')

这时候问题很快就会冒出来。

图书一多,变量会爆炸。 用户一多,也会越来越乱。 图书状态和借阅逻辑是分散的。 谁的数据归谁管,并不清晰。

也就是说,这种写法勉强能跑,但项目一旦稍微变大,代码就会越来越像一堆散落零件。

这正是类最适合出场的时候。

二、先别急着写代码,先识别项目里的对象

做面向对象项目,第一步不是上来就敲 class,而是先问自己:

这个项目里,真正重要的“角色”有哪些

在图书借阅系统里,很容易看出至少有三个核心角色:

图书 用户 图书馆

图书,有书名、作者、是否被借出,还会有借出、归还这些行为。 用户,有姓名、借阅记录,还会有查看借阅清单这种行为。 图书馆,要管理很多本书,也要处理借书、还书、展示图书信息这些动作。

你看,一旦这样去想,面向对象的味道就出来了。

以前你是在想“我要写哪些步骤”。 现在你开始想“这个系统里有哪些角色,各自负责什么”。

这就是典型的对象化思维。

三、第一步,先定义最基础的 Book 类

先从图书对象开始。

一本书最基本应该有什么信息?

书名 作者 借阅状态

它最基础应该会做什么?

展示信息 被借出 被归还

所以我们先写一个 Book 类。

classBook:    total_count = 0def__init__(self, title, author):        self.title = title        self.author = author        self._is_borrowed = False        Book.total_count += 1defshow_info(self):        status = '已借出'if self._is_borrowed else'可借阅'        print(f'书名:{self.title},作者:{self.author},状态:{status}')defborrow(self):if self._is_borrowed:            print(f'《{self.title}》已经被借走了')returnFalseelse:            self._is_borrowed = True            print(f'《{self.title}》借阅成功')returnTruedefreturn_book(self):ifnot self._is_borrowed:            print(f'《{self.title}》当前并没有被借出')returnFalseelse:            self._is_borrowed = False            print(f'《{self.title}》归还成功')returnTrue    @classmethoddefshow_total_count(cls):        print(f'当前系统中一共有 {cls.total_count} 本图书')

这一段代码里,已经把前面好几章的知识点真正串起来了。

__init__ 用来初始化图书对象。self.titleself.author 是实例属性。show_info()borrow()return_book() 是实例方法。total_count 是类属性,用来统计总图书数。show_total_count() 是类方法,用来展示整个类层面的共享信息。_is_borrowed 前面加下划线,是在表达:这是内部状态,外部最好不要直接乱改。

你会发现,一旦换成类写,图书这个角色立刻就完整了。

四、Book 类为什么比散乱变量更像“真实对象”

这一步特别值得你感受一下。

以前你可能只有:

book_name = 'Python 入门'book_author = '小王'book_is_borrowed = False

这些变量是散的。 而现在:

一本书的名字 一本书的作者 一本书的借阅状态 一本书该怎么借 一本书该怎么还

全都被组织到 Book 这个对象里了。

这正是封装的力量。

外部不需要知道 _is_borrowed 具体怎么变化。 它只需要通过:

book.borrow()book.return_book()

这些公开入口去操作就行。

这比让外部直接写:

book._is_borrowed = True

要稳得多,也自然得多。

五、第二步,再定义 User 类

接下来轮到用户对象。

一个用户最基本应该有什么?

姓名 借到的书

它又应该会做什么?

查看自己的借阅清单

所以可以写出下面这个类:

classUser:def__init__(self, name):        self.name = name        self.borrowed_books = []defshow_borrowed_books(self):ifnot self.borrowed_books:            print(f'{self.name} 当前还没有借任何书')else:            print(f'{self.name} 当前借阅的图书有:')for book in self.borrowed_books:                print(f' - 《{book.title}》')

这段代码虽然不长,但已经很清晰了。

用户对象自己保存自己的借阅记录。 用户对象自己知道怎么展示借阅清单。

你会发现,这种写法的最大好处之一就是:

谁的数据归谁管,越来越清楚。

书的数据归 Book 管。 用户的数据归 User 管。 不是所有东西都挤在全局变量里。

六、第三步,定义 Library 类,专门负责“系统管理”

现在图书和用户都有了,但还有一个问题:

借书和还书这种动作,到底由谁来协调

表面上看,借书既和图书有关,也和用户有关。 所以更自然的做法是,再引入一个“图书馆”角色,专门负责整个系统层面的管理工作。

它需要做的事可能包括:

添加图书 展示馆藏 处理借书 处理还书

所以可以定义一个 Library 类。

classLibrary:def__init__(self, name):        self.name = name        self.books = []defadd_book(self, book):        self.books.append(book)        print(f'图书馆新增图书:《{book.title}》')defshow_books(self):        print(f'欢迎来到 {self.name},当前馆藏如下:')for book in self.books:            book.show_info()defborrow_book(self, user, book):if book notin self.books:            print(f'《{book.title}》不在当前图书馆馆藏中')returnif book.borrow():            user.borrowed_books.append(book)            print(f'{user.name} 已将《{book.title}》加入借阅列表')defreturn_book(self, user, book):if book notin user.borrowed_books:            print(f'{user.name} 并没有借阅《{book.title}》')returnif book.return_book():            user.borrowed_books.remove(book)            print(f'{user.name} 已完成《{book.title}》归还')

这时候,整个小项目的结构就开始非常清楚了。

Book 管一本书自己的状态。User 管一个用户自己的借阅清单。Library 负责协调图书和用户之间的借阅关系。

这就是面向对象特别擅长的地方:

不是把所有逻辑糊成一团,而是让每个角色各管一摊。

七、完整跑一遍,你会更能体会“结构感”

下面我们把整个系统串起来运行一下。

book1 = Book('Python 入门''小王')book2 = Book('数据分析实战''老李')book3 = Book('自动化办公指南''阿明')user1 = User('张三')user2 = User('李四')library = Library('阳光图书馆')library.add_book(book1)library.add_book(book2)library.add_book(book3)print()library.show_books()print()library.borrow_book(user1, book1)library.borrow_book(user2, book1)library.borrow_book(user2, book2)print()user1.show_borrowed_books()user2.show_borrowed_books()print()library.show_books()print()library.return_book(user1, book1)library.return_book(user2, book3)print()library.show_books()

你不一定非要把输出背下来,但建议你自己脑子里过一遍流程。

图书被加入图书馆 图书馆展示馆藏 用户借书 如果书已经借出,就不能重复借 用户查看自己的借阅记录 用户归还图书 图书馆再展示一次最新状态

这时候你会明显感觉到:

整个项目像一个“小系统”了。 而不是几个孤零零的函数拼在一起。

八、为什么这个项目特别适合用类来重构

因为它里边天然存在多个“角色”。

图书不是一个变量,它是一个独立对象。 用户不是一个字符串,它也是一个独立对象。 图书馆更不是一个函数,它是一个协调多个对象的管理者。

你会发现,越是这种“现实角色很明确”的项目,用类来建模就越自然。

这也是为什么前面我们一直强调:

函数更擅长组织步骤 类更擅长组织角色

到了这个案例里,这句话就完全落地了。

九、现在来加入继承,让结构再进一层

前面这个版本已经能跑,而且已经很像真实小项目了。 但如果你学到这里,就停在“所有图书都一种类型”,那前面的继承和多态就还没真正落地。

现实里,图书馆里的书可能不止一种。

有纸质书 有电子书

它们有共同点:

都有书名 都有作者 都能展示信息

但它们也有差异:

纸质书有页数 电子书有文件大小

这时候,就非常适合用继承来表达。

先把 Book 当父类,然后让 PaperBook 和 EBook 继承它。

classBook:    total_count = 0def__init__(self, title, author):        self.title = title        self.author = author        self._is_borrowed = False        Book.total_count += 1defshow_info(self):        status = '已借出'if self._is_borrowed else'可借阅'        print(f'书名:{self.title},作者:{self.author},状态:{status}')defborrow(self):if self._is_borrowed:            print(f'《{self.title}》已经被借走了')returnFalseelse:            self._is_borrowed = True            print(f'《{self.title}》借阅成功')returnTruedefreturn_book(self):ifnot self._is_borrowed:            print(f'《{self.title}》当前并没有被借出')returnFalseelse:            self._is_borrowed = False            print(f'《{self.title}》归还成功')returnTrue

然后定义两个子类:

classPaperBook(Book):def__init__(self, title, author, pages):        super().__init__(title, author)        self.pages = pagesdefshow_info(self):        status = '已借出'if self._is_borrowed else'可借阅'        print(f'纸质书:《{self.title}》,作者:{self.author},页数:{self.pages},状态:{status}')classEBook(Book):def__init__(self, title, author, file_size):        super().__init__(title, author)        self.file_size = file_sizedefshow_info(self):        status = '已借出'if self._is_borrowed else'可借阅'        print(f'电子书:《{self.title}》,作者:{self.author},文件大小:{self.file_size}MB,状态:{status}')

这里就把继承、super()、方法重写都串起来了。

父类 Book 提供共性。 子类 PaperBook 和 EBook 增加自己的特有属性。 并且重写 show_info(),让同一个接口表现不同效果。

十、这时候,多态就真正落地了

注意 Library.show_books() 这个方法,我们根本不用改。

还是这样写:

defshow_books(self):    print(f'欢迎来到 {self.name},当前馆藏如下:')for book in self.books:        book.show_info()

为什么不用改?

因为不管 book 是 PaperBook 还是 EBook,它们都支持:

book.show_info()

这就是统一接口。

但不同对象执行后,会打印不同结果。 这就是多态。

我们来试一下:

library = Library('阳光图书馆')book1 = PaperBook('Python 入门''小王'320)book2 = EBook('数据分析实战''老李'15)book3 = PaperBook('自动化办公指南''阿明'280)library.add_book(book1)library.add_book(book2)library.add_book(book3)print()library.show_books()

这时候,外部只知道统一调用 show_info()。 至于有的显示页数,有的显示文件大小,那是不同子类自己决定的。

你会发现,这就是前一章讲的多态,在真实项目里非常自然的使用方式。

十一、封装在这个项目里又体现在哪里

很多人学封装的时候,容易停留在“哦,前面加下划线”这个层面。 但这个项目刚好能帮你把封装真正看明白。

比如图书的借阅状态 _is_borrowed。 外部理论上可以直接改,但正常设计下,最好不要这样干。 而应该通过:

book.borrow()book.return_book()

这些方法来改变状态。

这样做的意义在于:

借阅成功还是失败 归还是否合理 状态如何变更

这些规则都由对象自己控制。

这就是封装的价值:

不是暴露内部状态让外部乱改,而是提供合理入口让外部正常操作。

十二、为什么这个项目比过程式写法更容易扩展

这一步特别重要。

如果你一开始是过程式硬写,后来想加“电子书”这种新类型,往往会非常麻烦。因为你很多地方可能都写死了对某种图书结构的判断。

但现在用了类以后,扩展就顺很多。

想加新类型?

新建一个子类就行。

想让某类图书展示方式不同?

重写 show_info() 就行。

想让某类图书借阅规则不一样?

重写 borrow() 就行。

比如以后你还可以写一个“参考书”子类,规定它只能馆内阅读,不能借出:

classReferenceBook(Book):defborrow(self):        print(f'《{self.title}》属于参考书,不能外借')returnFalse

你看,只加一个类,整个系统就获得了新能力。 而图书馆里统一的借书流程几乎不用大改。

这就是面向对象在项目扩展上的优势。

十三、类属性在这个项目里也不是摆设

前面 Book.total_count 看起来像一个顺手加的计数器,但它其实非常实用。

比如你可以直接这样看总图书数:

Book.show_total_count()

或者补一个类方法:

@classmethoddefshow_total_count(cls):    print(f'当前系统中一共有 {cls.total_count} 本图书')

这时候你会更明显理解:

类属性不是某本书自己的信息 而是整个图书类共享的信息

这一章把它放进项目里,就是为了让你真正看到它的用武之地。 不是为了考试记名词,而是为了项目里真的能用上。

十四、静态方法也可以很自然地放进来

前面说过,静态方法最适合做那种“和类有关,但不依赖实例状态,也不依赖类状态”的工具逻辑。

在这个项目里,也很容易找到这样的场景。

比如判断书名是否合法:

classBook:    total_count = 0def__init__(self, title, author):        self.title = title        self.author = author        self._is_borrowed = False        Book.total_count += 1    @staticmethoddefis_valid_title(title):return len(title.strip()) > 0

调用时:

print(Book.is_valid_title('Python 入门'))print(Book.is_valid_title('   '))

你会发现,这个功能和 Book 主题有关,但它既不需要某本具体书的数据,也不需要整个类共享信息。 这就很适合写成静态方法。

这样一来,类属性、类方法、静态方法,就不是零散知识点,而是都在项目里找到位置了。

十五、这个项目真正锻炼你的,不只是 OOP 语法

说到底,这一章最重要的,不只是让你把几个类写出来,而是训练你一种更接近真实开发的思路:

先识别角色 再明确每个角色该负责什么 把共性抽出来 把个性留给子类 把内部状态保护起来 让外部通过统一接口来用

这套思路,你以后做学生管理系统、订单系统、用户系统、记账系统,其实都能用上。

所以这一章虽然写的是图书借阅,但它练的不是“图书”本身,而是“怎么用类去组织一个小项目”。

这才是真正值钱的地方。

十六、再给你一个更完整的整合版代码

下面给你一个更完整、适合自己敲一遍的整合版。

classBook:    total_count = 0def__init__(self, title, author):        self.title = title        self.author = author        self._is_borrowed = False        Book.total_count += 1defshow_info(self):        status = '已借出'if self._is_borrowed else'可借阅'        print(f'书名:{self.title},作者:{self.author},状态:{status}')defborrow(self):if self._is_borrowed:            print(f'《{self.title}》已经被借走了')returnFalse        self._is_borrowed = True        print(f'《{self.title}》借阅成功')returnTruedefreturn_book(self):ifnot self._is_borrowed:            print(f'《{self.title}》当前并没有被借出')returnFalse        self._is_borrowed = False        print(f'《{self.title}》归还成功')returnTrue    @classmethoddefshow_total_count(cls):        print(f'当前系统中一共有 {cls.total_count} 本图书')    @staticmethoddefis_valid_title(title):return len(title.strip()) > 0classPaperBook(Book):def__init__(self, title, author, pages):        super().__init__(title, author)        self.pages = pagesdefshow_info(self):        status = '已借出'if self._is_borrowed else'可借阅'        print(f'纸质书:《{self.title}》,作者:{self.author},页数:{self.pages},状态:{status}')classEBook(Book):def__init__(self, title, author, file_size):        super().__init__(title, author)        self.file_size = file_sizedefshow_info(self):        status = '已借出'if self._is_borrowed else'可借阅'        print(f'电子书:《{self.title}》,作者:{self.author},文件大小:{self.file_size}MB,状态:{status}')classUser:def__init__(self, name):        self.name = name        self.borrowed_books = []defshow_borrowed_books(self):ifnot self.borrowed_books:            print(f'{self.name} 当前还没有借任何书')else:            print(f'{self.name} 当前借阅的图书有:')for book in self.borrowed_books:                print(f' - 《{book.title}》')classLibrary:def__init__(self, name):        self.name = name        self.books = []defadd_book(self, book):        self.books.append(book)        print(f'图书馆新增图书:《{book.title}》')defshow_books(self):        print(f'欢迎来到 {self.name},当前馆藏如下:')for book in self.books:            book.show_info()defborrow_book(self, user, book):if book notin self.books:            print(f'《{book.title}》不在当前图书馆馆藏中')returnif book.borrow():            user.borrowed_books.append(book)            print(f'{user.name} 已将《{book.title}》加入借阅列表')defreturn_book(self, user, book):if book notin user.borrowed_books:            print(f'{user.name} 并没有借阅《{book.title}》')returnif book.return_book():            user.borrowed_books.remove(book)            print(f'{user.name} 已完成《{book.title}》归还')

这套代码并不算长,但它已经很像一个完整的小项目骨架了。

十七、你现在应该重点看懂什么

不是每一行都背下来。 而是重点看懂下面这些关系:

Book 为什么是父类PaperBook 和 EBook 为什么适合继承它show_info() 为什么能体现多态_is_borrowed 为什么体现了封装Library 为什么不适合只是一个普通函数集合User 为什么也应该是独立对象

只要这些关系看明白了,你就不是在机械抄代码,而是真的开始有项目建模能力了。

十八、做完这一章,你会发现面向对象终于“落地”了

前面十章,其实一直都像在搭骨架。

第71章到第75章,是在搭基础骨架。 第76章到第79章,是在补更完整的结构能力。 而这一章,就是把前面的骨架真正装进一个小系统里。

你会突然发现,那些原本看起来有点抽象的词:

类 对象 封装 继承 多态

到了项目里以后,其实都很具体。

不是为了定义而定义。 不是为了显得高级而高级。 而是真的能让代码更整洁、更清楚、更容易扩展。

这就是为什么学面向对象,不能只停留在背概念。 一定要进到项目里,才会真的通。

十九、本章小练习

你可以基于这一章的图书借阅系统,自己做两个升级版练习。

第一个练习,加入“借阅上限”功能。 比如每个用户最多只能借 3 本书。 这会迫使你去思考:这个规则应该放在 User 里,还是放在 Library.borrow_book() 里。

第二个练习,加入“参考书不能外借”功能。 写一个 ReferenceBook 子类,重写 borrow() 方法。 这会帮助你真正把继承和多态用起来。

如果你能自己把这两个功能补进去,这一阶段的内容就算真的吃透了。

二十、本章总结

这一章,我们没有再拆零碎知识点,而是把面向对象这一阶段真正收束成了一个完整的小项目。

你看到了怎么从真实业务里识别对象。 看到了如何用类来组织图书、用户、图书馆这些角色。 看到了封装如何保护内部状态。 看到了继承如何提取共性、减少重复。 看到了多态如何让统一接口在不同对象上表现不同。 也看到了类属性、类方法、静态方法在项目里到底能放在哪里。

到这里,第八阶段就算真正收束了。 你已经不只是会写几个类了,而是开始具备用类去组织一个小型真实项目的能力。

下一章,我们正式进入第九阶段:081|模块是什么:为什么 Python 代码可以拆文件

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-03 06:56:42 HTTP/2.0 GET : https://f.mffb.com.cn/a/498825.html
  2. 运行时间 : 0.333818s [ 吞吐率:3.00req/s ] 内存消耗:4,902.23kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=f3e92c626d718766070760a4ad8bc9a7
  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.000534s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000654s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.011428s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.005141s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000573s ]
  6. SELECT * FROM `set` [ RunTime:0.003187s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000607s ]
  8. SELECT * FROM `article` WHERE `id` = 498825 LIMIT 1 [ RunTime:0.037176s ]
  9. UPDATE `article` SET `lasttime` = 1783033002 WHERE `id` = 498825 [ RunTime:0.023309s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.003006s ]
  11. SELECT * FROM `article` WHERE `id` < 498825 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.015452s ]
  12. SELECT * FROM `article` WHERE `id` > 498825 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.025885s ]
  13. SELECT * FROM `article` WHERE `id` < 498825 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.059179s ]
  14. SELECT * FROM `article` WHERE `id` < 498825 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.066831s ]
  15. SELECT * FROM `article` WHERE `id` < 498825 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.004609s ]
0.335645s