zoukankan      html  css  js  c++  java
  • Shelve模块的使用

    一、定义

    Shelve是对象持久化保存方法,将对象保存到文件里面,缺省(即默认)的数据存储文件是二进制的。
    二、用途
    可以作为一个简单的数据存储方案。
    三、用法
    使用时,只需要使用open函数获取一个shelf对象,然后对数据进行增删改查操作,在完成工作、并且将内存存储到磁盘中,最后调用close函数变回将数据写入文件。
    四、关联模块Anydbm
    相同点:
    1.anydbm, shelve 都是对象持久化保存方法,将对象保存到文件里面,缺省的数据存储文件是二进制的。这两个模块允许我们将一个磁盘上的文件与一个”dict-like”对象(类字典对象)关联起来,操作这个“dict-like”对象,就像操作dict对象一项,最后可以将“dict-like”的数据持久化到文件。
    2.都可以使用open函数。

    区别:
    anydbm的key和value的类型必须都是字符串,而shelve的key要求必须是字符串,value则可以是任意合法的python数据类型。
    五、方法
    1.shelve.open(filename, flag=’c’, protocol=None, writeback=False):创建或打开一个shelve对象。shelve默认打开方式支持同时读写操作。
    filename是关联的文件路径。
    可选参数flag,默认为‘c’,如果数据文件不存在,就创建,允许读写;可以是: ‘r’: 只读;’w’: 可读写; ‘n’: 每次调用open()都重新创建一个空的文件,可读写。
    protocol:是序列化模式,默认值为None。具体还没有尝试过,从pickle的资料中查到以下信息【protocol的值可以是1或2,表示以二进制的形式序列化】

    2.shelve.close()
    同步并关闭shelve对象。
    注意:每次使用完毕,都必须确保shelve对象被安全关闭。同样可以使用with语句
    with shelve.open('spam') as db:
        db['eggs'] = 'eggs'
    六、writeback参数
    writeback:默认为False。当设置为True以后,shelf将会将所有从DB中读取的对象存放到一个内存缓存。当我们close()打开的shelf的时候,缓存中所有的对象会被重新写入DB。
    writeback方式有优点也有缺点。
    优点是减少了我们出错的概率,并且让对象的持久化对用户更加的透明了;但这种方式并不是所有的情况下都需要,首先,使用writeback以后,shelf在open()的时候会增加额外的内存消耗,并且当DB在close()的时候会将缓存中的每一个对象都写入到DB,这也会带来额外的等待时间。因为shelve没有办法知道缓存中哪些对象修改了,哪些对象没有修改,因此所有的对象都会被写入。

    注意:为了保存增、删、改的内容,建议显示的标明writeback=True。
    # 七、代码示例
    # 1.创建一个shelf对象,直接使用open函数即可
    
    import shelve
    s = shelve.open('test_shelf.db')         #
    try:
        s['kk'] = {'int': 10, 'float': 9.5, 'String': 'Sample data'}
        s['MM'] = [1, 2, 3]
    finally:
        s.close()
    
    # 2.如果想要再次访问这个shelf,只需要再次shelve.open()就可以了,然后我们可以像使用字典一样来使用这个shelf
    
    import shelve
    try:
        s = shelve.open('test_shelf.db')
        value = s['kk']
        print(value)
    finally:
        s.close()
    
    # 3.对shelf对象,增、删、改操作
    
    import shelve
    s = shelve.open('test_shelf.db', flag='w', writeback=True)
    try:
        # 增加
        s['QQQ'] = 2333
        # 删除
        del s['MM']
        # 修改
        s['kk'] = {'String': 'day day up'}
    finally:
        s.close()
    
    # 注意:flag设置为‘r’-只读模式,当程序试图去修改一个以只读方式打开的DB时,将会抛一个访问错误的异常。异常的具体类型取决于anydbm这个模块在创建DB时所选用的DB。异常举例:anydbm.error: need ‘c’ or ‘n’ flag to open new db
    
    # 4.循环遍历shelf对象
    
    import shelve
    s = shelve.open('test_shelf.db')
    try:
        # 方法一:
        for item in s.items():
            print ('键[{}] = 值[{}]'.format(item[0], s[item[0]]))
        # 方法二:
        for key, value in s.items():
            print(key, value)
    finally:
        s.close()
    
    # 5.备注一个错误:
    # open中的参数filename,起初认为需要手动新建一个.db,或者.dat的文件,目前电脑中无任何真正的数据库文件,所以采用了新建txt文件,修改后缀的方法创建.db,或者.dat的文件。
    # 解释器报错,提示内容为:"anydbm.error: db type could not be determined",
    # 原因是是filename已经存在,并且格式与shelve不符,所以提示 “db type could not be determined”。
    # 解决方法是,删除该文件。首次运行后会自动生成该filename文件。
    # 6.稍微复杂些的案例,实现一个简单提问式的数据库
    
    # encoding:utf-8
    # 2018/3/8
    
    # 简单的数据库
    
    import sys,shelve
    
    def print_help():
        '存储(增加)、查找、更新(修改)、循环打印、删除、退出、帮助'
        print('The available commons are: ')
        print('store    : Stores information about a person')
        print('lookup   : Looks up a person from ID numbers')
        print("update   : Update a person's information from ID number")
        print('print_all: Print all informations')
        print("delete   : Delete a person's information from ID number")
        print('quit     : Save changes and exit')
        print('?        : Print this message')
    
    
    def store_people(db):
        pid = input('Please enter a unique ID number: ')
        person = {}
        person['name'] = input('Please enter the name: ')
        person['age'] = input('Please enter the age: ')
        person['phone'] = input('Please enter the phone: ')
        db[pid] = person
        print("Store information: pid is %s, information is %s" % (pid, person))
    
    
    def lookup_people(db):
        pid = input('Please enter the number: ')
        field = input('What would you like to know? (name, age, phone) ')
        if pid in db.keys():
            value = db[pid][field]
            print("Pid %s's %s is %s" % (pid, field, value))
        else:
            print('Not found this number')
    
    
    def update_people(db):
        pid = input('Please enter the number: ')
        field = input('What would you like to update? (name, age, phone)  ')
        newvalue = input('Enter the new information: ')
        if pid in db.keys():
            value = db[pid]
            value[field] = newvalue
            print("Pid %s's %s update information is %s" % (pid, field, newvalue))
        else:
            print("Not found this number, can't update")
    
    
    def delete_people(db):
        pid = input('Please enter the number: ')
        if pid in db.keys():
            del db[pid]
            print("pid %s's information delete done" % pid)
        else:
            print( "Not found this number, can't delete")
    
    def print_all_people(db):
        print( 'All information are: ')
        for key, value in db.items():
            print(key, value)
    
    def enter_cmd():
        cmd = input('Please enter the cmd(? for help): ')
        cmd = cmd.strip().lower()
        return cmd
    
    def main():
        database = shelve.open('database201803.dat', writeback=True)
        try:
            while True:
                cmd = enter_cmd()
                if cmd == 'store':
                    store_people(database)
                elif cmd == 'lookup':
                    lookup_people(database)
                elif cmd == 'update':
                    update_people(database)
                elif cmd == 'print_all':
                    print_all_people(database)
                elif cmd == 'delete':
                    delete_people(database)
                elif cmd == '?':
                    print_help()
                elif cmd == 'quit':
                    return
        finally:
            database.close()
    
    if __name__ == '__main__':
        main()
    
    复制代码
    复制代码
    # shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;
    # key必须为字符串,而值可以是python所支持的数据类型
    # shelve模块(**)------可以当做数据库用,以后基本不会用,(可以很方面的往文件中写数据类型和读)
    import shelve             #存取很方便(可以做一个简单的数据存储方案)
    f=shelve.open(r'sheve.txt')
    f['stu1_info']={'name':'egon','age':18,'hobby':['piao','smoking','drinking']}   #
    f['stu2_info']={'name':'gangdan','age':53}
    f['school_info']={'website':'http://www.pypy.org','city':'beijing'}
    print(f['stu1_info']['hobby'])
    f.close()
     
    import shelve
    d=shelve.open(r'a.txt')                   #生成三个文件分别是:a.txt.baka.txt.data.txt.dir
    d['tom']={'age':18,'sex':'male'}         #存的时候会生成三个文件,不用管,是python的一种处理机制
    print(d['tom']['sex'])                   #可以取出字典中的key对应的value
    print(d['tom'])                          #取出tom对应的字典
    d.close()
    
    import shelve
    d=shelve.open(r'a.txt',writeback=True)    #writeback=True,对子字典修改完后要写回,否则不会看到修改后的结果
    d['egon']={'age':18,'sex':'male'}         #存的时候会生成三个文件,不用管,是python的一种处理机制
    d['egon']['age']=20                       #将年龄修改为20
    print(d['egon']['age'])                   #此时拿到的是修改后的年龄
    print(d['egon']['sex'])
    d.close()
  • 相关阅读:
    leetcode5 Longest Palindromic Substring
    leetcode17 Letter Combinations of a Phone Number
    leetcode13 Roman to Integer
    leetcode14 Longest Common Prefix
    leetcode20 Valid Parentheses
    leetcode392 Is Subsequence
    leetcode121 Best Time to Buy and Sell Stock
    leetcode198 House Robber
    leetcode746 Min Cost Climbing Stairs
    tomcat下使用druid配置jnid数据源
  • 原文地址:https://www.cnblogs.com/Centwei/p/14491213.html
Copyright © 2011-2022 走看看