鱼C论坛

 找回密码
 立即注册
查看: 1304|回复: 13

[已解决]通讯录作业题我做了个可保存反复用版本,碰到pickle 及函数编写疑问,

[复制链接]
发表于 2021-2-7 10:15:31 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
小甲鱼老师的作业题循环出现在不同的课节,帮我们温故知新,我干脆优化客户体验做了个可保存的 通讯录,省的每次打开要从头输入.
用到了pickle  模块, 但是发现 pickle  用 'rb' 模式打开就不能写入,用'wb'模式就不能读取,  网上看 有人用JASON 解决字典存入文档的问题,
我直接用''搬箱子''靠中间变量过了,  就是想知道是不是有还没学到的办法  能直接解决读写同时进行,  
另外,我铺代码可以看到,有许多行重复语句, 只是在输出打印时表述有些不同, 我感觉应该是能用函数形式减少代码量, 然后打印内容
按变量 形式 每次调用挂不同内容即可.   但是实践了一晚上, 没有成功,总是报缩进错误或者 段落不明  类似的错误, 因为我开始是把
if, else  分段了, 一半在函数里,一半是出了函数调用部分接上.  看到报错后,我试着整段包入函数,但是还是不给过.  不知道在构造函数时,是不是
有什么格式或语法框架上的要求
import pickle
import os
'''def input_part(express, result):                            # 函数调用不成功, 提示缩进错误类
     if name in contacts:
        print ('%s 的联系方式是: ' %(name) +str(contacts[name]))
        update=input(express)    
        if update in[ 'yes','YES','Y','y']:
            contacts[name]=str(input('请输入电话号码:'))
        else:
            continue
     else:
        print (result)'''


'''def update_part(express):                                     #  函数调用不成功,是否涉及到嵌套函数,
     update=input(express)  #重复段内容2
     if update in[ 'yes','YES','Y','y']:
        contacts[name]=str(input('请输入电话号码:'))         
     else:
        continue'''



print('| 欢迎进入选择界面|')
print('|   1,  查询联系人    |')
print('|   2,  添加联系人    |')
print('|   3.  删除联系人    |')
print('|   4.     退出           |')
if not os.path.exists('D:\\Python33\\35contact.pkl'):    #若没有就创建
    with open('D:\\Python33\\35contact.pkl', 'wb') as f:    #  'wb' 塞个空字典创建
        contacts=dict( )
        pickle.dump(contacts, f)
        f.close()

fnew=open('D:\\Python33\\35contact.pkl', 'rb')     # 若有了就读取  缓存到contacts 中
contacts=pickle.load(fnew)
fnew.close                                                          #  发现做了'rb'  就不能写, 做了'wb'就不给读
fnewnew=open('D:\\Python33\\35contact.pkl','wb')

while 1:
        select =int(input('请选择要使用功能:' ))
        if select==1:
               name=input('请输入姓名:')                     #重复段内容1
               if name in contacts:
                   print ('%s 的联系方式是: ' %(name) +str(contacts[name]))
                   update=input(' 需要修改%s的联系方式吗?'  %(name))    
                   if update in[ 'yes','YES','Y','y']:
                       contacts[name]=str(input('请输入电话号码:'))
                   else:
                        continue
               else:
                         print ('%s 的联系方式不存在' %(name))
                         update=input('需要添加%s 的联系方式吗?'  %(name))   #重复段内容2
                         if update in[ 'yes','YES','Y','y']:
                           contacts[name]=str(input('请输入电话号码:'))         
                         else:
                             continue
        if select==2:
               #input_part(' 需要修改%s的联系方式吗?'  %(name))
               name=input('请输入姓名:')                                                             #重复段内容1
               if name in contacts:
                   print ('%s 的联系方式是: ' %(name) +str(contacts[name]))
                   update=input(' 需要修改%s的联系方式吗?'  %(name))       # 重复段内容2
                   if update in[ 'yes','YES','Y','y']:
                       contacts[name]=str(input('请输入电话号码:'))
                   else:
                       continue
               if name not in contacts:
                       #update_part('需要添加%s 的联系方式吗?'  %(name))
                       update=input('需要添加%s 的联系方式吗?'  %(name))  #重复段内容2
                       if update in[ 'yes','YES','Y','y']:
                            contacts[name]=str(input('请输入电话号码:'))             
                       else:
                            continue
        if select==3:
               name=input('请输入姓名:')                                                            #重复段内容1
               if name in contacts:
                    print ('%s 的联系方式是: ' %(name) +str(contacts[name]))
                    update=input(' 需要删除%s的联系方式吗?'  %(name))    # 重复段内容2
                    if update in[ 'yes','YES','Y','y']:
                        contacts.pop(name)
                        print ('%s 的联系方式已删除' %(name))
                        continue
                    else:
                          continue
               if name not in contacts:
                             print ('%s 的联系方式不存在' %(name))
                             continue
        if select==4:
                update=input('确定要退出吗?')    
                if update in[ 'yes','YES','Y','y']:
                        pickle.dump(contacts,fnewnew)
                        fnewnew.close()
                        break    
                else:
                       continue
fcheck=open ('D:\\Python33\\35contact.pkl','rb')   #  测试输出保存结果
detail=pickle.load(fcheck)
print (detail)
fcheck.close()
最佳答案
2021-2-8 12:29:12
能看懂英文吗?能看懂的话就好办了

TutorialsTeacher

不知道你能不能打得开,试试
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-2-7 15:12:28 | 显示全部楼层
你这是学完了第一节课就直接跳过来学的吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-2-7 15:39:19 | 显示全部楼层
洋洋痒 发表于 2021-2-7 15:12
你这是学完了第一节课就直接跳过来学的吗

我觉得他可能是学了 pickle 以后,发现可以用在通讯录里面,就想尝试一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-2-7 15:42:54 | 显示全部楼层
读取了以后就关上,写入了以后也关上

实在记不住关上就 with open 呗

好像还没有什么情况是非得边读边写的吧?

你要是觉得读写太多次,就做两个函数,一个读,一个写,传参的值就是文件名字,等写入/读取完成后,再 fclose
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-2-7 15:47:35 From FishC Mobile | 显示全部楼层
本帖最后由 hrp 于 2021-2-7 16:00 编辑

程序运行过程中当然是对一个变量比如字典或列表进行操作啊,pickle只是在程序开始的时候读取到变量中,程序退出前一步将变量保存再退出,哪有每运行一步就读取或者保存一次的?

还有你的缩进真的太乱了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-2-7 15:49:00 | 显示全部楼层
Daniel_Zhang 发表于 2021-2-7 15:42
读取了以后就关上,写入了以后也关上

实在记不住关上就 with open 呗

我说的是他的缩进,我看好像有两个三个四个五个六个七个八个空格的缩进,我都惊呆了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-2-7 15:50:39 | 显示全部楼层
洋洋痒 发表于 2021-2-7 15:49
我说的是他的缩进,我看好像有两个三个四个五个六个七个八个空格的缩进,我都惊呆了

我还没注意
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-2-8 04:24:25 | 显示全部楼层
洋洋痒 发表于 2021-2-7 15:12
你这是学完了第一节课就直接跳过来学的吗

我用 IDle  写代码,   有时动一下就对不准, 我去 notepad ++   校对过缩进, 可是保存后再打开问题还是在,一长条红条
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-2-8 04:29:10 | 显示全部楼层
hrp 发表于 2021-2-7 15:47
程序运行过程中当然是对一个变量比如字典或列表进行操作啊,pickle只是在程序开始的时候读取到变量中,程序 ...

这里边有两种情形,   第一次打开需要判断是否存在指定文件, 如果不存在需要做创建写入操作,如果存在需要做读取操作,,   读取后在流程中会对数据进行编辑,  编辑后的结果需要再存入指定文件.  所以 即使不是同时做读和写, 一个运行周期里,  读和写的操作都要用到了,   所以想知道有没有通用的打开方式,又能读又能写, 这样我只需要一次打开和关闭
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-2-8 12:29:12 | 显示全部楼层    本楼为最佳答案   
能看懂英文吗?能看懂的话就好办了

TutorialsTeacher

不知道你能不能打得开,试试
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2021-2-9 06:00:23 | 显示全部楼层
Daniel_Zhang 发表于 2021-2-8 12:29
能看懂英文吗?能看懂的话就好办了

TutorialsTeacher

感谢CUE  这个文档, 介绍的更详细了一些,   我以为我看懂了 可是实操时,跟想象的不太一样, 就好比我想 不用第三方变量, 简化打开关闭的次数,   所以  第35   我把打开模式 从 rb   改为 rb+  让他能够写入,同时去掉  37 行关闭步骤,和三十八行调用第三方变量,   结果 一跑报错了,    Traceback (most recent call last):
  File "D:\Python33\contact_homework.py", line 36, in <module>
    contacts=pickle.load(fnew)

EOFError: Ran out of input
这个rb+ 不是二进制  读写模式吗?       这个 ran  out  of  input   怎么理解呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-2-9 11:39:45 | 显示全部楼层
Stack Overflow

CSDN

当出现报错信息的时候,可以自己将报错信息复制去百度或者谷歌进行搜索,例如:百度搜索 EOFError: Ran out of input 然后会出来很多结果,自己一一查看有没有类似的情况呗

没记错的话,Stack Overflow 在国内也是可以上的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2021-2-9 20:38:48 | 显示全部楼层

有查阅过,  还有好多处理方式,   估计是自己周边储备不足.  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-2-9 21:49:15 | 显示全部楼层
fazerse 发表于 2021-2-9 20:38
有查阅过,  还有好多处理方式,   估计是自己周边储备不足.

这就是学习的过程,一点点提升
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-16 13:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表