在我们用语言的过程中,比如要往文件内进行读写,那么势必要进行文件操作,那么咋操作呢?用眼睛直接看么?今天就定个小目标,把文件读写那些事扯一扯

文件操作

把大象放进冰箱分几步?

第一步:打开冰箱

第二步:把大象放进冰箱

第三步:把冰箱门关上

对文件的操作不也是一样么:

1、打开文件获取文件的句柄,句柄就理解为这个文件

2、通过文件句柄操作文件

3、关闭文件

辣么,我们就逐一来看一哈怎么进行这三步,文件的基本读写就完事了

打开文件

f = open('文件名','打开模式',指定字符集编码)

模式一般有几下几种方式:(这里的文件读写,指的是对于文件的操作)

r     只读模式:文件不存在的时候会报错;只能读不能写。如果进行写也会报错:not writeable

w   只写模式:文件不存在的话,帮你创建;打开文件会清空原来的文件内容,且不能读。可以理解为把原来的删除了,重新建了个文件

f = open('users2.txt','w',encoding='utf-8')
f.write('后天是周二')
f.close()

f = open('users2.txt','r',encoding='utf-8')
res = f.read()
print('第一次写入打开后的结果:%s\n'%(res))
f.close()

f = open('users2.txt','w',encoding='utf-8')
f.close()

f = open('users2.txt','r',encoding='utf-8')
res = f.read()
print('第二次写入打开后的结果:%s\n'%(res))
f.close()

结果:

第一次写入打开后的结果:后天是周二

第二次写入打开后的结果:

a    追加模式:文件不存在的话,帮你创建;不会清空原来文件的内容,但是不能读

f = open('users2.txt','a',encoding='utf-8')
f.write('后天是周二')
f.close()

f = open('users2.txt','r',encoding='utf-8')
res = f.read()
print('第一次写入打开后的结果:%s\n'%(res))
f.close()

f = open('users2.txt','a',encoding='utf-8')
f.write('再后天是周三')
f.close()

f = open('users2.txt','r',encoding='utf-8')
res = f.read()
print('第二次写入打开后的结果:%s\n'%(res))
f.close()

结果:

第一次写入打开后的结果:后天是周二

第二次写入打开后的结果:后天是周二再后天是周三

看到这里,你可能会问,这三种模式或多或少都有优缺点,就没有一种模式既能读又能写,能抗能打的么?

当然是 yes,升级版往下看:

 r+  读写模式:文件不存在会报错;可读,可写,可追加。要注意,默认写是从最开头写

# 第一次打开文件读
f = open('users2.txt','r+',encoding='utf-8')
res = f.read()
print('直接读的内容:%s'%(res))
f.close()

# 再次打开文件写
f = open('users2.txt','r+',encoding='utf-8')
f.write('abc')
res = f.read()
print('写完 abc 后的内容:%s'%(res))
f.close()

文件内的结果:

abc天是周二再后天是周三

打印结果:

直接读的内容:今天是周二再后天是周三
写完 abc 后的内容:天是周二再后天是周三

这里是因为我们再次打开写,文件指针是从最开始写的,那么就是从最开头写

我们可以发现:文件打开进行写,文件指针会指向最前面,然后往后面写,那么如果我先读完不关闭直接写呢?

f = open('users2.txt','r+',encoding='utf-8')
res = f.read()
print('直接读的内容:%s'%(res))

f.write('abc')
res2 = f.read()
print('写完 abc 后的内容:%s'%(res2))

结果:

文件内的结果:

今天是周二再后天是周三abc

打印的结果:

直接读的内容:今天是周二再后天是周三
写完 abc 后的内容:

从上边显而易见,只打开一次直接写的话,默认指针还是从最前面开始,read 一下,指针到最后,然后再写就是在最后面追加的内容了

w+  写读模式:文件不存在的话,帮你创建;打开文件会清空原来的文件内容,能读,但是由于清空了内容,读出来也是为空。

a+  追加读写模式:文件不存在的话,帮你创建;文件存在则往最后面追加内容,能写能读

∴ 要既能读也能写,就要用 r+ 或者 a+ 的方式,r+ 要追加写的话,要把文件指针移到最后;a+ 要读的话,要把文件指针移到最前

小结1:

  • 只要沾上 r 的,文件不存在会报错
  • 只要沾上 w 的,文件内容都会被清空

文件指针

个人理解:r  打开文件指针在最开头,w 打开文件指针在最开头,a 打开文件指针在最后

要理解这文件覆不覆盖,其实理解好文件指针就好了,那么啥是文件指针呢?简单理解为输入时的小光标,那么假设有个空文件,那么在一开始指针是指向文件内容的开端的,伴随着读写的进行指针一步一步往后挪。

那么,对于单次打开某文件,其实文件指针都指向了最开头,我们看一个例子:

假设有一个txt文件(filetest.txt),其中的内容如下:

今年是佩奇年,平安健康!
Python能做好多事!
今年要多写代码,写得多了也就熟练了!!

现在,我们写一段读的程序,

# coding=utf-8
import os
# os.getcwd()获取当前路径,即项目工程的目录
f = open('filetest.txt','r')
print("第一次读到的内容:\n", f.read())
print("第二次读到的内容:\n", f.read())

读取的结果如下:

第一次读到的内容:
今年是佩奇年,平安健康!
Python能做好多事!
今年要多写代码,写得多了也就熟练了!!
第二次读到的内容:

我们发现,第二次没有读出来任何内容,这是为什么呢?
从程序本身来看,前后两次调用 f.read() 函数,本意是将文件内容读两遍,可是第二次未读到任何内容。

针对这样的问题,其实是文件有一个文件指针(也叫 文件游标)的概念。实际上,当我们打开(open)这个文件的时候,此时,文件指针就定位在了文件的开头,当第一次调用 f.read() 函数时,相当于从文件指针的当前位置(即:文件开头)将这个文件全部读取出来;当第二次调用 f.read() 的时候,实际上此时文件指针已经定位在了文件的末尾,再次读取的时候,指向的内容就为空了。

下面再看一个例子:

# coding=utf-8
import os
# os.getcwd()获取当前路径,即项目工程的目录
f = open('filetest.txt','r')
print("第一次读到的内容:\n", f.read(2))  # 读取 2 个字节的内容
print("第二次读到的内容:\n", f.read(4))  # 读取 4 个字节的内容

读取的结果如下:

第一次读到的内容:
今年
第二次读到的内容:
是佩奇年

我们看到第二次读取到的内容并不是 【 今年是佩】,而是【是佩奇年】 ,那也就是说,当我们第一次f.read(2)的时候,当前文件指针已经定位到了第2个字节的位置,当第二次执行f.read(4)的时候,实际上是从当前文件指针位置开始读取4个字节的内容。

下面接着看另一个例子:

# coding=utf-8
import os
# os.getcwd()获取当前路径,即项目工程的目录
f = open('filetest.txt','r')
print("第一次读到的内容:", f.readline())
print("第二次读到的内容:", f.readline())

经过之前的解释,相信大家也能知道这段程序读取的结果,应该是读取文件的前两行内容,实际结果也是如此:

第一次读到的内容:今年是佩奇年,平安健康!
第二次读到的内容:Python能做好多事!

现在我们改变一下需求,要求两次读取的内容都是 文件的第一行 内容,该怎么办?
此时,我们应该要做的是改变文件指针的位置。

如何改变文件指针呢?这里需要用到 seek() 函数,其语法:seek(offset, wherece)

offset:偏移量,即表示文件指针所在的当前位置要偏移的字节数
wherece: 0 - 从文件开头;1 - 文件的当前位置; 2 - 文件的末尾

也就是说:快速移动到文件末尾f.seek(0,2),快速移动到文件开头f.seek(0)
有了这个 seek() 函数,我们就可以实现上面的需求了,如下:

# coding=utf-8
import os
# os.getcwd()获取当前路径,即项目工程的目录
f = open('filetest.txt','r')
print("第一次读到的内容:", f.readline())
f.seek(0,0)  # 重置文件指针到文件开头的第0个位置
print("第二次读到的内容:", f.readline())

结果如下:

第一次读到的内容:今年是佩奇年,平安健康!
第二次读到的内容:今年是佩奇年,平安健康!

那么,能不能查看当前文件指针的位置呢?答案是肯定的,就是 tell()函数。
例如:

# coding=utf-8
import os
# os.getcwd()获取当前路径,即项目工程的目录
f = open('filetest.txt','r')
print("当前文件指针的位置:", f.tell())
print("第一次读到的内容:", f.readline())
print("当前文件指针的位置:", f.tell())
print("第二次读到的内容:", f.read(6))
print("当前文件指针的位置:", f.tell())

结果如下:

当前文件指针的位置:0
第一次读到的内容:今年是佩奇年,平安健康!

当前文件指针的位置:26
第二次读到的内容:Python
当前文件指针的位置:32

这里总结一下关于文件指针的运用方式:

file.seek(offset, wherece)  # 移动 file 指针

file.seek(0,0)  # 移动指针指文件最开头

file.seek(9,1)  # 将文件指针从当前位置往后移动 9 个位置

file.seek(0,2)  # 移动指针指文件最末尾

file.tell()  # 读取当前文件指针,每次统计都是从文件头到当前指针所在位置

f.truncate()  # 截断,参照物永远都是文件开头

总结

  • r 打开,文件指针在最前;
  • w 打开,文件清空文件指针在最前;
  • a 打开,文件指针在最后面

文件模式

打开文件有以下几个模式:

模式 说明
r 只读模式:文件不存在的时候会报错;只能读不能写。如果进行写也会报错:not writeable
w 只写模式:文件不存在的话,帮你创建;不能读,重复打开文件会清空原来的文件内容。可以理解为把原来的删除了,重新建了个文件
a 追加模式:文件不存在的话,帮你创建;不会清空原来文件的内容,但是不能读
r+ 读写模式:可读、可写;可追加,如果打开的文件不存在的话,会报错
w+ 写读模式:使用w+的话,已经存在的文件内容会被清空,可以读到已经写的文件内容
a+ 追加读写模式:文件不存在则创建;存在则只追加内容,能写能读
rU "U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)
r+U "U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)
rb "b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)
wb "b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)
ab "b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)

常用操作文件方式

f.read()  # 读取文件内所有的内容

f.readlne()  # 读取文件内一行的内容,如果调用两次,那么会在往下读取一行,返回的是一个字符串

f.readlines()  # 读取文件内所有内容,按行转化成一个 list ,每一行都是这个 list 的一个元素

f.writelines()  # 括号内传一个 list ,会将 list 内的每一个元素写入

f.truncate()  # 从文件指针的位置开始清除内容到最后,所以要清空文件要先 f.seek(0,0)

f.truncae(size)  # 从文件当前指针的位置删出固定 size 的字符数

f.tell()  # 当前指针的位置

f.seek(offset, wherece)  # 移动文件指针

file.seek(0,0)  # 移动指针指文件最开头

file.seek(9,1)  # 将文件指针从当前位置往后移动 9 个位置

file.seek(0,2)  # 移动指针指文件最末尾

with open('a.txt') as f1, open('b.txt','w') as f2:  # 可以用 with 打开一个或多个文件,不用手动 close 去显式关闭,会自动给关闭(这里要注意是什么时候关闭,答案是:视情况而定)

场景1、把一个 list  = [123,456,789] 存入到 文件内,那么按照我们之前的方式:

list = [123,456,789]
for i in list:
    f.write(i+'\n')

那么简单方式:

其实 writelines() 里面内置了一个循环

list = [123,456,789]
f.writelines(list)

操作文件

功能 说明
f = open('file.txt','r+',encoding='utf-8') encoding参数可以指定文件的编码
f.readline() 读一行
f.readable() 判断文件是否可读
fr.writable() 判断文件是否可写
fr.encoding 打印文件的编码
f.read() 读取所有内容,大文件时不要用,
因为会把文件内容都读到内存中,
内存不够的话,会把内存撑爆
f.readlines() 读取所有文件内容,返回一个list,
元素是每行的数据,大文件时不要用,
因为会把文件内容都读到内存中,
内存不够的话,会把内存撑爆
f.tell() 获取当前文件的指针指向
f.seek(0) 把当前文件指针指向哪
f.write('爱情证书') 写入内容
f.fulsh() 写入文件后,立即从内存中把数据写到磁盘中
f.truncate() 清空文件内容
f.writelines(['爱情证书','孙燕姿']) 将一个列表写入文件中
f.close() 关闭文件

大文件修改

升级版的问题操作,以上只是基本的打开文件以及操作方式,那么思考一个问题,我们打开文件,读取/修改文件,都是和内存打交道。那么假设我们文件很大,那么会有什么问题?以及怎么避免掉这些问题呢?

往下看:

1、读取大文件显示

如果我们要读取一个大文件,如果直接将文案全部取出来存为一个变量打印,那样太费内存,循环每行打印可以节省内存。

with open('file.txt',encording = 'utf-8') as f:
    for line in f:
        print(line)

2、分析日志

  统计超过规定访问次数的 ip。假设有一个日志文件,该日志统计了本服务器被其他 ip 的访问记录,假设要预防攻击,则看有哪些 ip 频繁访问就好了,我们将 ip > 20 的,筛选出来。而且假设我们要统计没分钟内,访问量超过 20 次的 ip ,将其禁用,怎么做?

178.210.90.90 - - [04/Jun/2017:03:44:13 +0800] "GET /wp-includes/logo_img.php HTTP/1.0" 302 161 "http://nnzhp.cn/wp-includes/logo_img.php" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.99 Safari/533.4" "10.3.152.221"
178.210.90.90 - - [04/Jun/2017:03:44:13 +0800] "GET /blog HTTP/1.0" 301 233 "http://nnzhp.cn/wp-includes/logo_img.php" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.99 Safari/533.4" "10.3.152.221"
178.210.90.90 - - [04/Jun/2017:03:44:15 +0800] "GET /blog/ HTTP/1.0" 200 38278 "http://nnzhp.cn/wp-includes/logo_img.php" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.99 Safari/533.4" "10.3.152.221"…… 

那么日志文件一般比较大,行数较多,怎么处理呢?而且要解决每次对该日志进行统计的问题

解决方案:

1、打开文件;

2、依次读取文件内的每行;

3、读取每行里面的 ip 地址,利用 split() 的空格分割,取第一列数据

4、写一个字典,ip 存为 key,count 为 value ,假设 ip 在 key 内,则对应的 key 初始值为1 ,每次仔出现一次对应的 key ,则 value值 +1 ,这样可以统计到每个 ip 的出现次数,在打印出 value > 20 的 ip;

5、写一个延时,每 60s 调用一次

import time
point = 0
while True:
    with open('access.log',encoding='utf-8') as f:
        f.seek(point)
        ips  = {}
        for line in f:
            ip = line.split()[0] #取到ip地址
            if ip not in ips: #判断ip是否出现过,没有出现过ip的次数就是1
                ips[ip] = 1
            else:#出现过的话,次数就在原来的基础上+1
                ips[ip]+=1
        point = f.tell()#记录读完的位置
        for k,v in ips.items():
            if v>=20:
                print('有问题的ip地址是%s'%k)
    time.sleep(60)

3、大文件修改之——替换操作

假设有一个文件,一般来讲我们进行替换,比如说将 S 替换成 Python ,最无脑的方式:

  1. 先读取到所有的内容,修改
  2. 然后清空原有文件的内容,再写入新的
f = open('names.txt','a+')
f.seek(0)
res = f.read().replace('S','Python')
f.seek(0)
f.truncate()
f.write(res)

显而易见,直接 read 出整个文件,存为一个变量,进行替换操作,这样的影响是会占用大量内存!

因为把整个文件一次性取出来……那么怎么优化呢?

那我们每次取出一行,赋值给变量,然后写入一个新文件,再读取第二行,依次循环……再用新文件把旧的文件给替换,就 ok

with open('file.txt') as fr,with open('file_new','w') as fw: #这个是多文件的操作,打开两个文件,fr是读file.txt,fw是新建一个file_bak文件
for line in fr:#循环file.txt中的每一行
    new_line = line.replace('我','me')
    fw.write(new_line)#写到file_bak文件中
    fw.flush() #立即写入文件
os.remove('file.txt')
os.rename('file_new','file.txt')

4、修改文件内容

假设这里是每个同学的分数,我们要计算每个同学的平均分,加到每个童鞋的最后面

xiaohei,80,91,100,90
xiaohei,80,93,100,91
xiaohei,80,90,100,90

想一想,每一行都要修改如果逐行读取逐行系修改到本文件内,有点太难了。

简单粗暴的方式:

1、先读取到所有的内容,修改

2、然后清空原有文件的内容,再写入新的

f = open('account.txt','a+')
f.seek(0)
l = []
for line in f:
    line = line.strip()
    line_list = line.split(',')
    sum = int(line_list[1])+int(line_list[2])+int(line_list[3])    #sum = sum(int(line_list[1:]))  #切片取后三列再求和
    avg = sum//3  #这里 //3 是因为如果单个 / ,打印出的结果会保留好多位,这个是清除不必要的 0
    new_line = '%s,%s\n'%(line,avg)
    l.append(new_line)
f.seek(0)
f.truncate()
f.writelines(l)

这种方式不好的地方在哪?这还是把所有的东西都存下来,因为是把所有的值存成 list ,文件大也不好弄

高效率的方式:

1、打开2个文件 a b

2、a 只负责读,b 负责写,再将 a 删除,b 改成 a 文件名

import os
with open('account.txt') as  f,open('account2','w') as fw:
    for line in f:
        line = line.strip()
        line_list = line.split(',')
        sum = int(line_list[1])+int(line_list[2])+int(line_list[3])        #sum = sum(int(line[1:])  #切片算后三列和
        avg = sum//3  # 这里加两个 / 是因为一个 / 默认会有小数点,加两个就取整数
        new_line = '%s,%s\n'%(line,avg)
        fw.write(new_line)
        fw.flush() #立即写入文件,将缓冲区的内容写到磁盘里面。有时候 write 后没进入文件,那是因为缓冲区没有满,加入这个 flush 就能将缓冲区的内容写入
    os.remove('account.txt')
    os.rename('account2','account.txt')

json 操作

这个是一种特殊情况,假设我们要往文件内存东西,要存 key-value 形式,之前我们的操作是:key,value 这种方式写进去,虽然也是比较直观但是我们如果要把文件取出来读写的话,还是有些麻烦,要先一行一行把文件的内容读出来,转成一个字典,再用处理字典的方式进行处理完字符串再写入文件内。这样做太麻烦。

有没有一种方式,在文件内就存成类似字典的形式,且直观,而且取出数据有固定的方法,取成一个字典呢?

在接口测试我们看过 json 串,是存数据的,也是 key-value 形式,那么字典能不能以 json 形式存在文件内,取出的时候再将 json 转成字典呢?

首先我们要知道,存在文件内取出的东西都是字符串,写进去的也是字符串。你如果将一个字典写进文件是写入不了的

比如说:

d = {","abc":123,'bcd':'哈哈哈','sdfsd':'sdfs'}
f = open('user4.txt','w',encoding='utf-8')
f.write(d)

会报错:TypeError: write() argument must be str, not dict

那么我们先要将字典转成字符串,可以直接用 str(d) 方法,但是这样写入的还是一行,文件里面存的虽然像是字典,其实也是字符串,取出来还是要处理,因为不是 json 格式。

怎么将字典转成 json 串(json 也是个字符串)呢?利用 json 模块处理

1、字典转成 json 串 —— json.dumps

三步:1、打开文件;2、把字典 dumps 转成字符串;3、把字符串写到文件内

d = {","abc":123,'bcd':'哈哈哈','sdfsd':'sdfs'}
res = json.dumps(d,indent=4,ensure_ascii=False) #把字典转成json串,indent 是每一行前面的空格,ensure_ascii=False代表存入文件的格式不为ascii码,否则中文会为乱码
print(type(res))
print(res)

结果为:

<class 'str'>
{
        ",
        ",
        "abc": 123,
        "bcd": "哈哈哈",
        "sdfsd": "sdfs"
}

那么再将这个结果写入文件内就 ok:

如果存入文件为 json ,最好将文件名改成 xxx.json 这样里面的数字等是彩色显示,直观

f = open('a.json','w',encoding='utf-8')
f.write(res)

文件内的结果:

{
        ",
        ",
        "abc": 123,
        "bcd": "哈哈哈",
        "sdfsd": "sdfs"
}

2、json 串读取成字典 —— json.loads

存入看起来像是字典,但是其实还是字符串,是 json 串而已,那我们怎么将 json 取出来做字典呢?

三步:1、打开文件;2、读取文件内容;3、json.loads 把读到的字符串转换成字典

f = open('a.json',encoding='utf-8')
res = f.read()
print('res的类型',type(res))
d = json.loads(res) #把json串转成字典
print('字典:',d)

结果:

res的类型 <class 'str'>
字典: {', 'abc': 123, 'bcd': '哈哈哈', 'sdfsd': 'sdfs'}

注意:如果要使用 json.loads 那么传入的必须是 json.dumps 或者 json.dump 写入的,如果直接将字典强制性 strf(dict) 写入,键值对显示的是 {'ksy':'value'} 但是 json 串的key-value 形式用的是  {"key":"value"} 双引号,所以强制转换写入的,用 json.load 读取不出来,请勿给自己挖坑

3、升级版本 —— json.dump 和 json.load

上述的其实只是针对字符串处理,比如我们在打印的时候可以将字典 json.dumps 格式化打印出来。那么针对于写入文件以及读取文件的 json 形式,我们用更简单的方式:

两步:1、打开文件;2、json.dump 写入

d= {
        "error_code": 0,
        "stu_info": [
                {
                        "id": 8485,
                        "name": "矿泉水2",
                        "sex": "未知",
                        "age": 38,
                        "addr": "天通苑",
                        "grade": "双子座",
                        ",
                        "gold": 100
                }
        ]
}

fw = open('kqs.json','w',encoding='utf-8')
json.dump(d,fw,indent=4,ensure_ascii=False)

load 可以少写一步,只有两步:1、打开文件;2、load

f = open('user4.txt',encoding='utf-8')
result = json.load(f)
print(result)

小总结:带 s 的是 string 相关的,要利用变量写进去;不带 s 的是文件相关的,直接写入文件内

作业

要求:

1、商品存在文件里面

2、添加商品的时候,商品存在的就不能添加了,数量只能是大于0的整数,价格可以是小数、整数,但是只能是大于0的

  • 商品名称
  • 商品价格
  • 商品数量

3、删除的商品的时候输入商品名称,商品不存在,要提示

4、修改商品的时候

  • 商品名称
  • 商品价格
  • 商品数量

5、查看商品,输入商品名称,查询到商品的信息

import json
#常量
FILENAME='product.json' #全局变量

def write_file(d):
    with open(FILENAME,'w',encoding='utf-8') as fw:
        json.dump(d,fw,indent=4,ensure_ascii=False)

def read_file():
    with open(FILENAME,encoding='utf-8') as fw:
        return json.load(fw)

def check_int(num): #校验是否为大于0的整数
    num = str(num)
    if num.isdigit() and int(num)>0:
        return True

def check_price(num):
    num = str(num)
    if num.count('.')==1:
        left,right = num.split('.') # 0.0
        if left.isdigit() and right.isdigit() and int(right)>0:
            return True
    elif check_int(num):
        return True

all_product = read_file()  #获取到所有的商品

def add_product():
    name = input('name:').strip()
    count = input('count:').strip()
    price = input('price:').strip()
    if name and count and price:
        if not check_int(count):
            print('商品数量错误')
        elif not check_price(price):
            print('价格错误')
        elif name in all_product:
            print('商品已存在')
        else:
            all_product[name]= {'price':price,'count':count}
            write_file(all_product)
            print('商品添加成功!')
    else:
        print('不能为空!')

def edit_product():
    while True:
        name = input('name:').strip()
        if name in all_product:
            break
        elif name=='q':
            quit('退出')
    count = input('count:').strip()
    price = input('price:').strip()
    if name and count and price:
        all_product[name] = {'price': price, 'count': count}
        write_file(all_product)
        print('修改成功!')
    else:
        print('不能为空!')

def show_product():
    while True:
        name = input('name:').strip()
        if name in all_product:
            print(all_product.get(name))
            break
        elif name=='all':
            print(json.dumps(all_product,indent=4,ensure_ascii=False))
            break
        elif name=='q':
            quit('退出')

def del_product():
    while True:
        name = input('name:').strip()
        if name in all_product:
            all_product.pop(name)
            write_file(all_product)
            print('删除成功!')
        elif name=='q':
            quit('退出')

func_map = {
    ":add_product,
    ":del_product,
    ":edit_product,
    ":show_product,
    ":quit
}
for i in range(4):
    choice = input('请输入你的选择:\n'
                   '1、添加商品\n'
                   '2、删除商品\n'
                   '3、修改商品信息\n'
                   '4、查看商品\n'
                   '5、退出')

    if choice in func_map:
        func_map.get(choice)()
    else:
        print('请输入正确的选项!')

Python(三)——文件操作的更多相关文章

  1. 孤荷凌寒自学python第三十五天python的文件操作之针对文件操作的os模块的相关内容

     孤荷凌寒自学python第三十五天python的文件操作之针对文件操作的os模块的相关内容 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.打开文件后,要务必记得关闭,所以一般的写法应当 ...

  2. 孤荷凌寒自学python第三十三天python的文件操作初识

     孤荷凌寒自学python第三十三天python的文件操作初识 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天开始自学python的普通 文件操作部分的内容. 一.python的文件打开 ...

  3. Python :open文件操作,配合read()使用!

    python:open/文件操作 open/文件操作f=open('/tmp/hello','w') #open(路径+文件名,读写模式) 如何打开文件 handle=open(file_name,a ...

  4. python的文件操作及简单的用例

    一.python的文件操作介绍 1.文件操作函数介绍 open() 打开一个文件 语法:open(file, mode='r', buffering=-1, encoding=None, errors ...

  5. [转]python file文件操作--内置对象open

    python file文件操作--内置对象open   说明: 1. 函数功能打开一个文件,返回一个文件读写对象,然后可以对文件进行相应读写操作. 2. file参数表示的需要打开文件的相对路径(当前 ...

  6. 员工管理系统+字符编码+Python代码文件操作

    员工管理系统+字符编码+Python代码文件操作 1.员工管理系统 1.1  debug 代码调试 1.先使用鼠标左键在需要调试的代码左边点击一下(会出现一个红点)2.之后右键点击debug运行代码 ...

  7. Python 常见文件操作的函数示例(转)

    转自:http://www.cnblogs.com/txw1958/archive/2012/03/08/2385540.html # -*-coding:utf8 -*- ''''' Python常 ...

  8. python中文件操作的六种模式及对文件某一行进行修改的方法

    一.python中文件操作的六种模式分为:r,w,a,r+,w+,a+ r叫做只读模式,只可以读取,不可以写入 w叫做写入模式,只可以写入,不可以读取 a叫做追加写入模式,只可以在末尾追加内容,不可以 ...

  9. python中文件操作的其他方法

    前面介绍过Python中文件操作的一般方法,包括打开,写入,关闭.本文中介绍下python中关于文件操作的其他比较常用的一些方法. 首先创建一个文件poems: p=open('poems','r', ...

  10. Python常见文件操作的函数示例

    # -*-coding:utf8 -*- ''''' Python常见文件操作示例 os.path 模块中的路径名访问函数 分隔 basename() 去掉目录路径, 返回文件名 dirname() ...

随机推荐

  1. ASP.NET Core2.2 IExceptionFilter

    用vs2017建立一个ASP.NET Core Web应用程序并选择MVC框架,自动生成了 Startup的类,并配置了错误处理方式: if (env.IsDevelopment()) { app.U ...

  2. Vue语法学习第一课——插值

    学习关于Vue的插值语法 ① 文本值 : "Mustache"语法,即双大括号 <span>Message:{{msg}}</span> 注:双大括号中的m ...

  3. APICloud-数据存储

    APICloud 共有四种数据存储 1.file:目录操作,文件操作 文件存储方式,用于图片.文档的上传.下载.删除.管理. 2.db:本地 sqlite 数据库 用于离散数据的存储. 3.loacl ...

  4. CSS多行文字超出隐藏加省略号

    overflow: hidden; text-overflow:ellipsis; white-space: nowrap; 限制行数 overflow: hidden; text-overflow: ...

  5. 用Webstrom搭建Vue项目

    一.首先要有Node.js   Webpack环境 1.Node.js:是一个能够在服务器端运行JavaScript的开放源代码,跨平台JavaScript运行环境.Node采用Google开发的V8 ...

  6. 【转】反编译D-Link路由器固件程序并发现后门

    固件是D-link无线路由器(型号:DIR-100 revA)的固件程序 v1.13.使用工具Binwalk,很快的就从中发现并提取出一个只读SquashFS文件系统,没用多大功夫我就将这个固件程序的 ...

  7. 【python】带图片验证码的登录自动化实战

    近期在跟进新项目的时候,整体的业务线非常之长,会一直重复登录退出不同账号的这个流程,所以想从登录开始实现部分的自动化.因为是B/S的架构,所以采用的是selenium的框架来实现.大致实现步骤如下: ...

  8. 路径定义前+r

    定义文件路径时前面加个r 例如 firstfolder = r"C:\Users\1261\Desktop\" 不对其中的符号进行转义

  9. vue+koa实现简单的图书小程序(3)

    实现一个今年过了多少天的组件的记录我们使用了原生的微信小程序开发文档里的组件 “Progress” 并不需要自己去写: https://developers.weixin.qq.com/minipro ...

  10. 二进制按位与(&) 按位或(|)  异或运算(^)

    1.参加运算的两个数据,按照二进制进行按位与的运算. 运算规则:0&0=0;   0&1=0;    1&0=0;     1&1=1; 即:两位同时为“1”,结果才为 ...