一、 文件处理
- 一般步骤,分为三步,打开、操作、关闭
#. 打开文件,得到文件句柄并赋值给一个变量
f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r
#. 通过句柄对文件进行操作
data=f.read()
#. 关闭文件
f.close()
2 . with方式省去close()
打开一个文件包含两部分资源:操作系统级打开的文件+应用程序的 变量。在操作完毕一个文件时,必须把与该文件的这两部分资源一个不落地回收,回收方法为:
1、f.close() #回收操作系统级打开的文件
2、del f #回收应用程序级的变量
其中del f一定要发生在f.close()之后,否则就会导致操作系统打开的文件还没有关闭,白白占用资源,
而python自动的垃圾回收机制决定了我们无需考虑del f,这就要求我们,在操作完毕文件后,一定要记住f.close()
但是使用with关键字来帮我们管理上下文,自动执行f.close()
with open('a.txt','r') as read_f,open('b.txt','w') as write_f:
data=read_f.read()
write_f.write(data)
练习:
利用文件处理,模拟linux命令cp
import sys
if len(sys.argv) != 3:
print('usage: cp source_file target_file')
sys.exit()
source_file,target_file=sys.argv[1],sys.argv[2]
with open(source_file,'rb') as read_f,open(target_file,'wb') as write_f:
for line in read_f:
write_f.write(line)
基于seek实现linux命令tail -f 功能
## tail -f 功能
import time
with open('wenjian','rb') as read_f:
read_f.seek(0,2)
while True:
for line in read_f:
if line:
print(line.decode('utf-8'))
else:
time.sleep(0,2)
修改文件内容
##修改文件内容
# import os
#
# with open('wenjian','r',encoding='utf-8') as read_f , open('wenjian.swap','w',encoding='utf-8') as write_f:
# for line in read_f:
# line = line.replace('b','kk')
# write_f.write(line)
#
# os.remove('wenjian')
# os.rename('wenjian.swap','wenjian')
二 、函数
函数分为内置函数和自定义函数
定义:
def 函数名(参数1,参数2,参数3,…):
”’注释”’
函数体
return 返回的值
/#函数名要能反映其意义
1、位置参数:按照从左到右的顺序定义的参数
位置形参:必选参数
位置实参:按照位置给形参传值
2、关键字参数:按照key=value的形式定义的实参
无需按照位置为形参传值
注意的问题:
1. 关键字实参必须在位置实参右面
2. 对同一个形参不能重复传值
3、默认参数:形参在定义时就已经为其赋值
可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参)
注意的问题:
1. 只在定义时赋值一次
2. 默认参数的定义应该在位置形参右面
3. 默认参数通常应该定义成不可变类型
4、可变长参数:
可变长指的是实参值的个数不固定
而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*args,**kwargs
练习:
1、写函数,,用户传入修改的文件名,与要修改的内容,执行函数,完成批了修改操作
2、写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数
3、写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5。
4、写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
5、写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。
6、写函数,检查字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
dic = {“k1”: “v1v1”, “k2”: [11,22,33,44]}
PS:字典中的value只能是字符串或列表
def modify(file,old,new):
import os
with open(file,'r',encoding='utf-8') as read_f , open('.swap','w',encoding='utf-8') as write_f:
for line in read_f:
if old in line:
line = line.replace(old,new)
write_f.write(line)
os.remove(file)
os.rename('.swap',file)
def count(string):
digit_num = 0
space_num = 0
char_num = 0
qita_num = 0
for i in string:
if i.isdigit():
digit_num += 1
elif i.isalpha():
char_num += 1
elif i.isspace():
space_num += 1
else:
qita_num += 1
print('数字有{0},字母有{1},空格有{2},其他有{3}'.format(digit_num,char_num,space_num,qita_num))
def bolang(name):
if len(name) > 5:
print(len(name))
else:
print(len(name),'< 5')
def err(listne):
if len(listne) > 2:
return listne[:2]
else:
return listne
def jishu(li):
newli = []
for i in range(0,len(li)):
if not i % 2 == 0:
newli.append(li[i])
return newli
def zidian(dic):
new_key = []
new_value = []
for key in dic:
new_key.append(key)
if len(dic[key]) > 2:
dic[key] = dic[key][:2]
new_value.append(dic[key])
else:
new_value.append(dic[key])
new_dic = dict(zip(new_key,new_value))
return new_dic
if __name__ == '__main__':
# modify('wenjian','k','a')
# count('asdsf3534dgfdg&*(')
# bolang(['3','32','3444','11111',111,323])
# aa = err(['q','33','455'])
# print(aa)
# print(jishu(['1','2',3,4,5,6,7,8,9]))
aa = zidian({'a':'12345','b':[1,2,3,4,5,6],'c':'2','d':['2']})
print(aa)
作业,模拟sql语句操作文件
def ParseWhere(dic,context):
'''处理where条件后面的条件'''
wc = []
for bb in dic['where']:
cc = bb.split()
if cc[1] == '>':
cc[0] = context[cc[0]]
rr = cc[0] > cc[2]
wc.append(rr)
if cc[1] == '=':
cc[0] = context[cc[0]]
rr = cc[0] == cc[2]
wc.append(rr)
if cc[1] == '<':
cc[0] = context[cc[0]]
rr = cc[0] < cc[2]
wc.append(rr)
if cc[1] == 'like':
cc[0] = context[cc[0]]
rr = cc[2] in cc[0]
wc.append(rr)
for w in wc:
if w == False:
return False
return True
def ParseSql(sql):
'''处理用户输入的sql语句,变成字典'''
import re
if 'where' in sql:
keys = ['select', 'from', 'where']
value = []
tery = re.split('select|from|where', sql)
# 将输入的sql语句变成字典类型
for k in range(1, len(tery)):
value.append(tery[k].strip())
dic_select = dict(zip(keys, value))
dic_select['select'] = dic_select['select'].split(',')
dic_select['from'] = dic_select['from'].split('.')
dic_select['where'] = dic_select['where'].split('and')
return dic_select
else:
keys = ['select', 'from']
value = []
tery = re.split('select|from', sql)
# 将输入的sql语句变成字典类型
for k in range(1, len(tery)):
value.append(tery[k].strip())
dic_select = dict(zip(keys, value))
dic_select['select'] = dic_select['select'].split(',')
dic_select['from'] = dic_select['from'].split('.')
return dic_select
def ParseSelect(dic_select,context):
for k in dic_select['select']:
if k == '*':
for v in context.values():
print(v, end=' ')
#print('')
#break
else:
print(context[k], end=' ')
print('')
def select(sql):
'''执行select操作的主函数'''
count = 0
dic_select = ParseSql(sql)
with open(dic_select['from'][0], 'r', encoding='utf-8') as read_f:
# 获得文件第一行的表头信息
title = read_f.readline().split()
# 利用表头信息,和下面的内容,组成字典
for line in read_f:
res = line.split()
context = dict(zip(title, res))
if 'where' in dic_select:
if ParseWhere(dic_select,context):
ParseSelect(dic_select,context)
count += 1
else:
ParseSelect(dic_select,context)
count += 1
print('操作条数:' ,count)
return count
def update(sql):
print("update from ", sql)
import smilar
import re
import os
bb = []
for i in re.split('update|set|where', sql):
bb.append(i.strip())
title = ['update', 'set', 'where']
dic = dict(zip(title, bb[1:]))
dic['where'] = dic['where'].split('and')
# print(dic['update'])
with open(dic['update'], 'r', encoding='utf-8') as read_f, open('.swap', 'w', encoding='utf-8') as write_f:
title = read_f.readline().split()
title_str = ' '.join(title)
write_f.write(title_str)
write_f.write('\n')
# 利用表头信息,和下面的内容,组成字典
for line in read_f:
res = line.split()
context = dict(zip(title, res))
if smilar.ParseWhere(dic, context):
fuck = dic['set'].split('=')
cover = {'id': 0, 'name': 1, 'age': 2, 'phone': 3, 'dept': 4, 'enroll_time': 5}
type = cover[fuck[0].strip()]
old = line.split()[type]
new = fuck[1].strip()
line = line.replace(old, new)
write_f.write(line)
os.remove(dic['update'])
os.rename('.swap', dic['update'])
def delete(sql):
print("ok , delete", sql)
import smilar
import re,os
bb = []
for i in re.split('delete from|where', sql):
bb.append(i.strip())
title = ['table', 'where']
dic = dict(zip(title, bb[1:]))
dic['where'] = dic['where'].split('and')
with open(sql.split()[2], 'r', encoding='utf-8') as read_f, open('.swap', 'w', encoding='utf-8') as write_f:
title = read_f.readline().split()
title_str = ' '.join(title)
write_f.write(title_str)
write_f.write('\n')
# 利用表头信息,和下面的内容,组成字典
for line in read_f:
res = line.split()
context = dict(zip(title, res))
if not smilar.ParseWhere(dic, context):
write_f.write(line)
os.remove(sql.split()[2])
os.rename('.swap', sql.split()[2])
def ParseInsert(sql):
import re
aa = re.findall('(\([^()]*\))', sql)
title = ['name', 'age', 'phone', 'dept', 'enroll_time']
for i in aa:
print(i)
ko = re.split('[\(\)]', i)
tmp_list = ko[1].split(',')
my_dic = dict(zip(title, tmp_list))
return my_dic
def insert(sql):
print("insert into ", sql)
aa = ParseInsert(sql)
ph = []
with open(sql.split()[2], 'r', encoding='utf-8') as read_f:
for line in read_f:
ph.append(line.split()[3])
if aa['phone'] in ph:
print('主键phone冲突')
else:
st = str(len(ph))
for k in aa.values():
st = st + ' ' + k
with open(sql.split()[2], 'a', encoding='utf-8') as write_f:
write_f.write(st)
write_f.write('\n')
dic = {'select':select,'update':update,'delete':delete,'insert':insert}
if __name__ == '__main__':
while True:
try:
laji = input("输入sql语句操作:")
cmd = laji.split()
func = cmd[0]
if cmd[0] not in dic:
print("语法错误:请检查您的sql语句")
else:
dic[func](laji)
except:
print("语法错误,重新输入!")