15 项目实操:图书馆管理系统

希望这个程序可以做到:

15 项目实操:图书馆管理系统

我们要思考:需要定义多少个类?每个类有怎样的属性和方法?

15 项目实操:图书馆管理系统

第一种用法是使用类生成实例对象。类作为实例对象的模版,每个实例创建后,都将拥有类的所有属性和方法,减少代码量,同一化和模块化

第二种用法是用类将多个函数(方法)打包封装在一起,让类中的方法相互配合,避免传参过多或过度使用global

回到项目:我们的处理对象是每本具体的书,而每本书都有自己的属性信息,所以我们可以定义一个Book类,利用Book类创建一个个书的实例,绑定属性(对应用法1)。

而这个管理系统的运行主体,是多个可供选择的功能的叠加,所以我们可以创建一个系统运行类BookManager,将查询书籍、添加书籍等功能封装成类中的方法以供调用(对应用法2)。

我们的预期效果是当实例化这个系统运行类的时候,会出现一个菜单,能让用户选择不同的功能,如下图所示:

15 项目实操:图书馆管理系统

那么,将上述要编写的两个类整理一下,这个程序的骨架就是这样:(注释里对应每个方法的功能)

15 项目实操:图书馆管理系统

接下来,我们可以先按这个框架来编写代码,解决编写过程中出现的每一个问题,让目标得实现。

代码实现,逐步执行

定义Book类

根据需求,每本书的基本属性都要有四个:书名、作家、推荐语和借阅状态。所以,我们可以利用初始化方法init,让实例被创建时自动获得这些属性。

15 项目实操:图书馆管理系统

为了后续方便参数传递,借阅状态state采用默认参数,用0来表示'未借出',1来表示'已借出'。

初始化方法定义完成后,一旦实例对象被创建,这几个属性就存在且可随时调用。

我们注意到系统里有一个功能是显示所有书籍信息,所以我们可以在Book类定义一个方法,当调用这个方法时,就能够打印出这本书的信息,加上循环,就能打印所有书籍的信息。希望的格式是这样的:

15 项目实操:图书馆管理系统

那么,我们可以在初始化方法的基础上定义一个show_info()方法,打印出每本书的信息:

15 项目实操:图书馆管理系统

只要在类中定义了str(self)方法,那么当使用print打印实例对象的时候,就会直接打印出在这个方法中return的数据。直接把上述代码里的方法名show_info(self)替换成str(self),留意最后一行调用的代码,然后点击运行:

类BookManager的编写

回顾:

15 项目实操:图书馆管理系统
15 项目实操:图书馆管理系统

用户输入数字执行相应的功能,程序内部调用的逻辑应该是:

15 项目实操:图书馆管理系统

这里需要用到多层条件判断语句

15 项目实操:图书馆管理系统

来看看show_all_book()方法,它的功能是打印出系统里所有书籍的信息。为了方便调试,验证代码是否写对了,我们可以先往书籍系统里添加几本书籍,也就是创建Book类的实例对象。

class Book:
    def __init__(self, name, author, comment, state = 0):
        self.name = name
        self.author = author
        self.comment = comment
        self.state = state

    def __str__(self):
        if self.state == 0:
            status = '未借出'
        else:
            status = '已借出'
        return '名称:《%s》 作者:%s 推荐语:%s\n状态:%s ' % (self.name, self.author, self.comment, status)

class BookManager:
    def __init__(self):
        book1 = Book('惶然录','费尔南多·佩索阿','一个迷失方向且濒于崩溃的灵魂的自我启示,一首对默默无闻、失败、智慧、困难和沉默的赞美诗。')
        book2 = Book('以箭为翅','简媜','调和空灵文风与禅宗境界,刻画人间之缘起缘灭。像一条柔韧的绳子,情这个字,不知勒痛多少人的心肉。')
        book3 = Book('心是孤独的猎手','卡森·麦卡勒斯','我们渴望倾诉,却从未倾听。女孩、黑人、哑巴、醉鬼、鳏夫的孤独形态各异,却从未退场。', 1)

manager = BookManager()

上面的代码,在BookManager类的初始化方法中创建了3个Book类的实例对象。换言之,当创建实例manager时,book1、book2、book3就会生成。

当有多个对象的时候,就要考虑数据存储的方式。由于每个Book实例是并列平行的关系,所以可以用列表来存储。于是可以在类的开头定义一个空列表books,方便其他方法调用,然后把刚刚创建的Book实例添加到这个列表里。

15 项目实操:图书馆管理系统

如此一来,列表books里的每个元素都是基于Book类创建的实例对象,所以每个元素会【自动拥有Book类的方法】__str__。我们可以验证一下:

15 项目实操:图书馆管理系统

发现了吗?这个结果和我们想要定义的显示书籍信息的方法show_all_book()是一样的,所以我们可以把最后几行代码封装成方法。

15 项目实操:图书馆管理系统

我们将两个类的代码组合在一起,直接运行,遇到输入请输入数字1:

15 项目实操:图书馆管理系统

执行结果:

15 项目实操:图书馆管理系统

接下来我们来看第二个功能:添加书籍add_book()。

代码结构应该是这样的:当输入数字2的时候,就会跳转到对应的方法:

15 项目实操:图书馆管理系统

如果注释没有看懂,可以结合下面的数据流转图再理解一下:

15 项目实操:图书馆管理系统

把之前写好的代码整合在一起。

class Book:
 
    def __init__(self, name, author, comment, state = 0):
        self.name = name
        self.author = author
        self.comment = comment
        self.state = state
 
    def __str__(self):
        status = '未借出'
        if self.state == 1:
            status = '已借出'
        return '名称:《%s》 作者:%s 推荐语:%s\n状态:%s ' % (self.name, self.author, self.comment, status)

class BookManager:

    books = []

    def __init__(self):
        book1 = Book('惶然录','费尔南多·佩索阿','一个迷失方向且濒于崩溃的灵魂的自我启示,一首对默默无闻、失败、智慧、困难和沉默的赞美诗。')
        book2 = Book('以箭为翅','简媜','调和空灵文风与禅宗境界,刻画人间之缘起缘灭。像一条柔韧的绳子,情这个字,不知勒痛多少人的心肉。')
        book3 = Book('心是孤独的猎手','卡森·麦卡勒斯','我们渴望倾诉,却从未倾听。女孩、黑人、哑巴、醉鬼、鳏夫的孤独形态各异,却从未退场。',1)
        self.books.append(book1)
        self.books.append(book2)
        self.books.append(book3)

    def menu(self):
        print('欢迎使用流浪图书管理系统,每本沉默的好书都是一座流浪的岛屿,希望你有缘发现并着陆,为精神家园找到一片栖息地。\n')
        while True:
            print('1.查询所有书籍\n2.添加书籍\n3.借阅书籍\n4.归还书籍\n5.退出系统\n')
            choice = int(input('请输入数字选择对应的功能:'))
            if choice == 1:
                self.show_all_book()
                # self是实例对象的替身
            elif choice == 2:
                self.add_book()
            elif choice == 3:
                self.lend_book()
                
    def show_all_book(self):
        for book in self.books:
            print(book)
    
    def add_book(self):
        new_name = input('请输入书籍名称:')
        new_author =  input('请输入作者名称:')
        new_comment = input('请输入书籍推荐语:')
        new_book = Book(new_name, new_author, new_comment)
        self.books.append(new_book)
        print('书籍录入成功!\n')

来看第三个功能:借阅书籍lend_book()

借阅功能lend_book()要怎么实现呢?可以先想想我们平时找人借东西,会出现哪几种情况?

15 项目实操:图书馆管理系统

这里有两个要点:1. 怎么判断这本书在不在系统里;2.怎么判断这本书有没有被借走。

首先,判断在不在系统里,我们可以采用遍历书籍列表books的方式,一旦输入的书籍名称和列表元素中的书籍名称出现匹配,就证明系统里有这本书。其次,如果书在系统里,有没有被借走可以根据实例属性state来判断,0表示'未借出',1表示'已借出'。

给出这两个判断的代码

class BookManager:

    books = []     
    def __init__(self):
        book1 = Book('惶然录','费尔南多·佩索阿','一个迷失方向且濒于崩溃的灵魂的自我启示,一首对默默无闻、失败、智慧、困难和沉默的赞美诗。')
        book2 = Book('以箭为翅','简媜','调和空灵文风与禅宗境界,刻画人间之缘起缘灭。像一条柔韧的绳子,情这个字,不知勒痛多少人的心肉。')
        book3 = Book('心是孤独的猎手','卡森·麦卡勒斯','我们渴望倾诉,却从未倾听。女孩、黑人、哑巴、醉鬼、鳏夫的孤独形态各异,却从未退场。',1)
        self.books.append(book1)
        self.books.append(book2)
        self.books.append(book3)

    def lend_book(self):
        borrow_name = input('请输入你想借阅的书籍名称:')
        for book in self.books:
        # 遍历列表,此时books有三个元素,即book1,book2,book3三个实例
            if book.name == borrow_name:
                # 如果列表中有实例的属性name和输入的书籍名称相等
                if book.state == 1:
                # 借阅状态为'已借出'
                    print('你来晚一步,这本书已经被借走了噢')
                    break
                    # 一旦有对象满足条件,则退出for循环
                else:
                # 借阅状态为'未借出'
                    print('借阅成功!借了不看会变胖噢~')
                    book.state = 1
                    break
            else:
                continue
          # 如果不满足book.name == borrow_name,则继续循环(这两行可以省略)  
        else:
            print('这本书暂时没有收录在系统里呢')

注意这里有几个层级的else语句,我们可以看到最外层结构是for…else,表示的是当for循环里的对象都遍历完毕后,才执行else子句的内容。

也就是说,当列表里没有对象能够满足if book.name == borrow_name条件时,才会打印else子句的那一句话。(如果for循环内部有break子句,也不会执行)

代码是完成了,但归还书籍的时候,也会碰到类似的逻辑。为了不写重复的代码,我们可以【额外在类中定义一个方法】,专门检查输入的书名是否在书籍列表里。

换句话说:将上面lend_book()方法中检测书名的代码抽出来,封装成一个函数。这样就可以在借书和还书的代码里直接调用,不用两处重复写同样的代码。

15 项目实操:图书馆管理系统

为什么要分别返回书籍名称和None值呢?相信你读完下面的代码,就可以理解了。

15 项目实操:图书馆管理系统

我们将目前为止的代码,整合在一起

class Book:
 
    def __init__(self, name, author, comment, state = 0):
        self.name = name
        self.author = author
        self.comment = comment
        self.state = state
 
    def __str__(self):
        status = '未借出'
        if self.state == 1:
            status = '已借出'
        return '名称:《%s》 作者:%s 推荐语:%s\n状态:%s ' % (self.name, self.author, self.comment, status)
 
class BookManager:
    #存储书籍的列表,每一个元素都是Book的实例对象
    books = []
    def __init__(self):
        book1 = Book('惶然录','费尔南多·佩索阿','一个迷失方向且濒于崩溃的灵魂的自我启示,一首对默默无闻、失败、智慧、困难和沉默的赞美诗。')
        book2 = Book('以箭为翅','简媜','调和空灵文风与禅宗境界,刻画人间之缘起缘灭。像一条柔韧的绳子,情这个字,不知勒痛多少人的心肉。')
        book3 = Book('心是孤独的猎手','卡森·麦卡勒斯','我们渴望倾诉,却从未倾听。女孩、黑人、哑巴、醉鬼、鳏夫的孤独形态各异,却从未退场。',1)
        self.books.append(book1)
        self.books.append(book2)
        self.books.append(book3)
 
    def menu(self):
        print('欢迎使用流浪图书管理系统,每本沉默的好书都是一座流浪的岛屿,希望你有缘发现并着陆,为精神家园找到一片栖息地。\n')
        while True:
            print('1.查询所有书籍\n2.添加书籍\n3.借出书籍\n4.归还书籍\n5.退出系统\n')
            choice = int(input('请输入数字选择对应的功能:'))
            if choice == 1:
                self.show_all_book()
            elif choice == 2:
                self.add_book()
            elif choice == 3:
                self.lend_book()
            elif choice == 4:
                self.return_book()
            elif choice == 5:
                print('感谢使用!')
                break
 
    def show_all_book(self):
        for book in self.books:
            print(book)
            print('')

    def add_book(self):
        new_name = input('请输入书籍名称:')
        new_author =  input('请输入作者名称:')
        new_comment = input('请输入书籍推荐语:')
        new_book = Book(new_name, new_author, new_comment)
        self.books.append(new_book)
        print('书籍录入成功!\n')

    def check_book(self,name):
        for book in self.books:
            if book.name == name:
                 return book 
        else:
            return None

    def lend_book(self):
        name = input('请输入书籍的名称:')
        res = self.check_book(name)

        if res != None:
            if res.state == 1:
                print('你来晚了一步,这本书已经被借走了噢')
            else:
                print('借阅成功,借了不看会变胖噢~')
                res.state = 1
        else:
            print('这本书暂时没有收录在系统里呢')
 
manager = BookManager()
manager.menu()

return_book功能添加最终结果:

class Book:
 
    def __init__(self, name, author, comment, state = 0):
        self.name = name
        self.author = author
        self.comment = comment
        self.state = state
 
    def __str__(self):
        status = '未借出'
        if self.state == 1:
            status = '已借出'
        return '名称:《%s》 作者:%s 推荐语:%s\n状态:%s ' % (self.name, self.author, self.comment, status)
 
class BookManager:

    books = []
    def __init__(self):
        book1 = Book('惶然录','费尔南多·佩索阿','一个迷失方向且濒于崩溃的灵魂的自我启示,一首对默默无闻、失败、智慧、困难和沉默的赞美诗。')
        book2 = Book('以箭为翅','简媜','调和空灵文风与禅宗境界,刻画人间之缘起缘灭。像一条柔韧的绳子,情这个字,不知勒痛多少人的心肉。')
        book3 = Book('心是孤独的猎手','卡森·麦卡勒斯','我们渴望倾诉,却从未倾听。女孩、黑人、哑巴、醉鬼、鳏夫的孤独形态各异,却从未退场。',1)
        self.books.append(book1)
        self.books.append(book2)
        self.books.append(book3)
 
    def menu(self):
        print('欢迎使用流浪图书管理系统,每本沉默的好书都是一座流浪的岛屿,希望你有缘发现并着陆,为精神家园找到一片栖息地。\n')
        while True:
            print('1.查询所有书籍\n2.添加书籍\n3.借阅书籍\n4.归还书籍\n5.退出系统\n')
            choice = int(input('请输入数字选择对应的功能:'))
            if choice == 1:
                self.show_all_book()
            elif choice == 2:
                self.add_book()
            elif choice == 3:
                self.lend_book()
            elif choice == 4:
                self.return_book()
            else:
                print('感谢使用!愿你我成为爱书之人,在茫茫书海里相遇。')
                break
 
    def show_all_book(self):
        print('书籍信息如下:')
        for book in self.books:
            print(book)
            print('')

    def add_book(self):
        new_name = input('请输入书籍名称:')
        new_author =  input('请输入作者名称:')
        new_comment = input('请输入书籍推荐语:')
        new_book = Book(new_name, new_author, new_comment)
        self.books.append(new_book)
        print('书籍录入成功!\n')

    def check_book(self,name):
        for book in self.books:
            if book.name == name:
                 return book 
        else:
            return None

    def lend_book(self):
        name = input('请输入书籍的名称:')
        res = self.check_book(name)

        if res != None:
            if res.state == 1:
                print('你来晚了一步,这本书已经被借走了噢')
            else:
                print('借阅成功,借了不看会变胖噢~')
                res.state = 1
        else:
            print('这本书暂时没有收录在系统里呢')
    
    def return_book(self):
        name = input('请输入归还书籍的名称:')
        res = self.check_book(name)
        if res == None:
            print('没有这本书噢,你恐怕输错了书名~')
        else:
            if res.state == 0:
                print('这本书没有被借走,在等待有缘人的垂青呢!')
            else:
                print('归还成功!')
                res.state = 0
 
manager = BookManager()
manager.menu()

课后练习

在Book类的基础上,创建一个子类FictionBook类代表虚构类图书,并改造初始化方法,增加一个默认参数type = '虚构类'

1.请你在代码的基础上,创建一个【子类】FictionBook。

2.在子类【改造】父类的初始化方法,添加一个虚构类的【属性】,让程序能够打印出实例book的相关信息。

class Book:

    def __init__(self, name, author, comment, state = 0):

        self.name = name

        self.author = author

        self.comment = comment

        self.state = state

 

# 创建一个Book类的子类 FictionBook
class FictionBook(Book):

    def __init__(self, name, author, comment, state = 0, type = '虚构类'):

        Book.__init__(self, name, author, comment, state = 0)

        self.type = type

    def __str__(self):

        status = '未借出'

        if self.state == 1:

            status = '已借出'

        return '类型:%s 名称:《%s》 作者:%s 推荐语:%s\n状态:%s ' % (self.type, self.name, self.author, self.comment, status)

book = FictionBook('囚鸟','冯内古特','我们都是受困于时代的囚鸟')
print(book)

发布者:LJH,转发请注明出处:https://www.ljh.cool/7906.html

(0)
上一篇 2022年9月13日 上午11:42
下一篇 2022年9月14日 下午7:39

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注