fazerse 发表于 2021-2-7 10:15:31

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

小甲鱼老师的作业题循环出现在不同的课节,帮我们温故知新,我干脆优化客户体验做了个可保存的 通讯录,省的每次打开要从头输入.
用到了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))
      update=input(express)   
      if update in[ 'yes','YES','Y','y']:
            contacts=str(input('请输入电话号码:'))
      else:
            continue
   else:
      print (result)'''


'''def update_part(express):                                     #函数调用不成功,是否涉及到嵌套函数,
   update=input(express)#重复段内容2
   if update in[ 'yes','YES','Y','y']:
      contacts=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))
                   update=input(' 需要修改%s的联系方式吗?'%(name))   
                   if update in[ 'yes','YES','Y','y']:
                     contacts=str(input('请输入电话号码:'))
                   else:
                        continue
               else:
                         print ('%s 的联系方式不存在' %(name))
                         update=input('需要添加%s 的联系方式吗?'%(name))   #重复段内容2
                         if update in[ 'yes','YES','Y','y']:
                           contacts=str(input('请输入电话号码:'))         
                         else:
                           continue
      if select==2:
               #input_part(' 需要修改%s的联系方式吗?'%(name))
               name=input('请输入姓名:')                                                             #重复段内容1
               if name in contacts:
                   print ('%s 的联系方式是: ' %(name) +str(contacts))
                   update=input(' 需要修改%s的联系方式吗?'%(name))       # 重复段内容2
                   if update in[ 'yes','YES','Y','y']:
                     contacts=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=str(input('请输入电话号码:'))            
                     else:
                            continue
      if select==3:
               name=input('请输入姓名:')                                                            #重复段内容1
               if name in contacts:
                  print ('%s 的联系方式是: ' %(name) +str(contacts))
                  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-7 15:12:28

{:10_277:}你这是学完了第一节课就直接跳过来学的吗

Daniel_Zhang 发表于 2021-2-7 15:39:19

洋洋痒 发表于 2021-2-7 15:12
你这是学完了第一节课就直接跳过来学的吗

我觉得他可能是学了 pickle 以后,发现可以用在通讯录里面,就想尝试一下{:10_248:}

Daniel_Zhang 发表于 2021-2-7 15:42:54

读取了以后就关上,写入了以后也关上

实在记不住关上就 with open 呗

好像还没有什么情况是非得边读边写的吧?{:10_245:}

你要是觉得读写太多次,就做两个函数,一个读,一个写,传参的值就是文件名字,等写入/读取完成后,再 fclose

hrp 发表于 2021-2-7 15:47:35

本帖最后由 hrp 于 2021-2-7 16:00 编辑

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

还有你的缩进真的太乱了{:10_247:}

洋洋痒 发表于 2021-2-7 15:49:00

Daniel_Zhang 发表于 2021-2-7 15:42
读取了以后就关上,写入了以后也关上

实在记不住关上就 with open 呗


我说的是他的缩进,我看好像有两个三个四个五个六个七个八个空格的缩进,我都惊呆了

Daniel_Zhang 发表于 2021-2-7 15:50:39

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

{:10_328:}我还没注意

fazerse 发表于 2021-2-8 04:24:25

洋洋痒 发表于 2021-2-7 15:12
你这是学完了第一节课就直接跳过来学的吗

我用 IDle写代码,   有时动一下就对不准, 我去 notepad ++   校对过缩进, 可是保存后再打开问题还是在,一长条红条

fazerse 发表于 2021-2-8 04:29:10

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

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

Daniel_Zhang 发表于 2021-2-8 12:29:12

能看懂英文吗?能看懂的话就好办了

TutorialsTeacher

不知道你能不能打得开,试试{:10_245:}

fazerse 发表于 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+ 不是二进制读写模式吗?       这个 ranoutofinput   怎么理解呢?

Daniel_Zhang 发表于 2021-2-9 11:39:45

Stack Overflow

CSDN

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

没记错的话,Stack Overflow 在国内也是可以上的{:10_254:}

fazerse 发表于 2021-2-9 20:38:48

Daniel_Zhang 发表于 2021-2-9 11:39
Stack Overflow

CSDN


有查阅过,还有好多处理方式,   估计是自己周边储备不足.

Daniel_Zhang 发表于 2021-2-9 21:49:15

fazerse 发表于 2021-2-9 20:38
有查阅过,还有好多处理方式,   估计是自己周边储备不足.

这就是学习的过程,一点点提升
页: [1]
查看完整版本: 通讯录作业题我做了个可保存反复用版本,碰到pickle 及函数编写疑问,