第二章
本章内容
1.装饰器
2.生成器
3.迭代器
4.内置函数
5.相对路径,绝对路径
6.(time)时间模块,random
7.json,pickle
8.shutil(复制,压缩,解压)
9.shelve
10.xml
11.configparser
12.hashlib
13.logging
14.re(正则表达式)
装饰器
装饰器
定义 :本质是函数,(装饰其他函数)就是为其他函数添加附加功能
原则:1.不能修改被装饰的函数的源代码
2.不能修改被装饰的函数的调用方式
实现装饰器的知识储备:
1.函数即使变量
2.高阶函数
3.嵌套函数
高阶函数+嵌套函数=装饰器
高阶函数
def bar():
time.sleep(3)
print('in the bar')
def test1(func):
start_time=time.time()
func()
stop_time=time.time()
print("thn func run time is %s" %(start_time-stop_time))
test1(bar)
高阶函数+return
def bar():
time.sleep(3)
print('in the bar')
def test2(func):
print(func)
return func
bar=test2(bar)
bar()
装饰器
def timer(func):
def deco():
start_time=time.time()
func()
stop_time=time.time()
print('thn func run time is %s'%(start_time-stop_time))
return deco
@timer
def test1():
time.sleep(3)
print('in the test1')
@timer
def test2():
time.sleep(3)
print('in the test2')
test1()
test2()
@timer == test1=timer(test1)
装饰器实参形参
def timer(func):
def deco(*args,**kwargs):
start_time=time.time()
func(*args,**kwargs)
stop_time=time.time()
print("testas,testas %s" %(start_time-stop_time))
return deco
@timer
def test1(name,age):
time.sleep(1)
print("testasd",name,age)
@timer
def test2():
time.sleep(1)
print("testas")
test1('alex',55)
test2()
复杂装饰器
1 user,passwd = "alex",'abc789' 2 3 def auth(auth_type): 4 def outer_wrapper(func): 5 def wrapper(*args,**kwargs): 6 if auth_type == "local": 7 username=input("Username:").strip() 8 password=input("Password:").strip() 9 if username == user and password == passwd: 10 print("\033[35mUser has passed authentication\033[0m") 11 res = func(*args,**kwargs) 12 return res 13 else: 14 exit("\033[36merror password\033[0m") 15 elif auth_type == "ldap": 16 print("\033[32m----ldap----\033[0m") 17 return wrapper 18 return outer_wrapper 19 20 @auth(auth_type="local") 21 def index(): 22 print("\033[33mwelcom to index page\033[0m") 23 24 @auth(auth_type="ldap") 25 def home(): 26 print("\033[32mwelcom to home page\033[0m") 27 return "from home" 28 29 @auth 30 def bbs(): 31 print("\033[31mwelcom to bbs page\033[0m") 32 33 home() 34 index() 35 bbs()
生成器
列表生成器
[ i*2 fro i inr ange(10)] [ func(i) for i inrange(10) ]
生成器
生成器
(i*2 for i in range(10))
def fib(max):
n,a,b = 0,0,1
while n<max:
#print(b)
yield b
a,b =b ,a+b
n = n+1
return '---done---'
f = fib(10)
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
抓取错误
while True:
try:
x = next(f)
print('h:',x)
except StopIteration as e:
print("Generator return value:", e.value)
break
def consumer(name):
print("%s 准备吃包子啦!"%name)
while True:
baozi = yield
print("包子[%s]来了,被[%s]吃了!"%(baozi,name))
# c= consumer("ZhangSan")
# c.__next__()
def producer(name):
c = consumer('A')
c2 = consumer('B')
c.__next__()
c2.__next__()
print("准备包子啦!")
for i in range(10):
time.sleep(1)
print("做了一个包子!")
c.send(i)
c2.send(i)
producer("alex")
迭代器
可以直接用于for 循环的对象统称为迭代器对象:Iterable
可以被next()函数调用不断返回下一值得对象成为迭代器
判断一个对象是否为迭代器对象:(terable)
from collections import Iterable
isinstance([],Iterable)
True
isinstance({}, Iterable)
True
isinstance('abc', Iterable)
True
isinstance((x for x in range(10)), Iterable)
True
isinstance(100, Iterable)
False
判断一个对象是否为迭代器
把list、dict、str等Iterable变成Iterator可以使用iter()函数
from collections import Iterator
isinstance(iter([]), Iterator)
True
isinstance(iter('abc'), Iterator)
True
内置函数
隐藏函数:类似三元运算
calc = lambda n:3 if n<4 else n print(calc(2))
filter
筛选大于5的
res = filter(lambda n:n>5,range(10))
for i in res:
print(i)
functools
从1+到10
import functools res = functools.reduce( lambda x,y:x+y,range(10)) print(res)
sorted
排序
字典转换成列表按keys排序
a = {6:2,8:0,1:4,-5:6,99:11,4:22}
print( sorted(a.items()))
字典转换成列表按value排序
print(sorted(a.items(),key=lambda x:x[1]))
zip():拉链
a = [1,2,3,4]
b = ['a','b','c','d']
for i in zip(a,b):
print(i)
(1, 'a')
(2, 'b')
(3, 'c')
(4, 'd')
__import__
按字符串导入模块
__import__("decorator")
绝对路径,相对路径import os,sys
打印当前文件所在文件的路径:相对路径 print(__file__) 打印当前文件绝对路径 print(os.path.abspath(__file__)) 打印上及目录 print(os.path.dirname(os.path.abspath(__file__))) 把文件的上上级目录加入到环境变量 BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) os.path.join()

内置参数详解 https://docs.python.org/3/library/functions.html?highlight=built#ascii
ATM + 购物商城

creditcard.py
启动程序
1 #!/usr/bin/python env 2 # _*_ coding:utf-8 _*_ 3 import os,sys 4 5 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 6 sys.path.append(BASE_DIR) 7 8 from foo import index,main 9 10 11 msg_dict = { 12 '0': main.mycc, 13 '1': main.money, 14 '2': main.Transfer_accounts, 15 '3': main.repayment, 16 '4': main.create_user, 17 '5': main.del_user,} 18 19 #开始程序 20 @main.auth 21 def cart(): 22 fag = True 23 while fag: 24 for k,v in enumerate(index.menu_dict): 25 print(k,v) 26 choice = input("请选择:>>") 27 if choice == 'q': 28 exit() 29 if choice.isdigit(): 30 choice = int(choice) 31 if choice <= len(index.menu_dict): 32 key_1 = list(index.menu_dict.keys())[choice] 33 #tag = True 34 while fag: 35 for v in index.menu_dict[key_1]: 36 print(v) 37 user_choice = input("请选择:") 38 if user_choice.isdigit(): 39 user_choice=user_choice 40 msg_dict[user_choice]() 41 if user_choice == 'q': 42 break 43 44 cart()
locking
信用卡锁定用户文件
1 zhuangsan 2 lisi
admin
信用卡用户密码文件
1 {"admin": {"Password": "789", "Credit": 1270, "Name": "abc", "Balance": 730, "User_id": "001"}, "han": {"Password": "789", "Credit": 13051, "Name": "han", "Balance": 2499, "User_id": 106}, "gh": {"Password": "789", "Credit": 14000, "Name": "gh", "Balance": 1000, "User_id": 103}}
sp_user
购物商城用户密码文件
1 admin 789
docs
空
1 kong
file_dir.py
文件处理程序
1 #!/usr/bin/python env 2 # _*_ encoding:utf-8 _*_ 3 4 import os,sys,json 5 6 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 7 sys.path.append(BASE_DIR) 8 9 10 #新建用户写入文件 11 def add_user(data): 12 with open(BASE_DIR + '\databases\\admin','w+',encoding='utf-8') as f: 13 data=json.dump(data,f) 14 return add_user 15 16 17 #atm写入操作日志 18 def atm_log(log): 19 with open(BASE_DIR + '\logs\\atm','a+',encoding='utf-8') as f: 20 f.write(log) 21 return atm_log 22 23 24 #锁定用户文件 25 def locking(log): 26 with open(BASE_DIR+'\conf\\locking','a+',encoding='utf-8') as f: 27 f.write(log) 28 return locking 29 30 31 #读取锁定文件 32 def sd(user): 33 with open(BASE_DIR +'\conf\\locking','r',encoding='utf-8') as f: 34 for i in f: 35 if user in i: 36 print("\033[36m用户%s已锁定,无法登陆!\033[0m" % user) 37 exit() 38 return sd 39 40 41 #读取用户信息 42 def get_user_data(): 43 with open(BASE_DIR + '\databases\\admin','r') as f: 44 user_data = json.load(f) 45 return user_data 46 47 48 49 #用户登录日志 50 def login_log(log): 51 with open(BASE_DIR + '\logs\\login','a+',encoding='utf-8') as f: 52 f.write(log) 53 #user_login = json.dump(log,f,ensure_ascii=False) 54 return login_log 55 56 57 #错误日志 58 def error_log(log): 59 with open(BASE_DIR + '\logs\\errorlog','a+',encoding='utf-8') as f: 60 f.write(log) 61 #user_error = json.dump(log,f) 62 return error_log 63 64 65 #读取购物用户账号密码 66 def user_r(user): 67 with open(BASE_DIR + '\databases\\sp_user','r+',encoding='utf-8') as f: 68 for i in f: 69 if i.startswith(user): 70 return True 71 else: 72 return False 73 74 75 #写入用户 76 def user_w(user): 77 with open(BASE_DIR + '\databases\\sp_user','a+' ,encoding='utf-8') as f: 78 f.write(user) 79 return user_w 80 81 82 #购物历史记录写入文件 83 def sp_log(log): 84 with open(BASE_DIR + '\logs\\shopping_log', 'a+', encoding='utf-8') as f: 85 f.write(log) 86 return sp_log
index.py
主页菜单程序
1 #!/usr/bin/python env 2 # _*_ encoding:utf-8 _*_ 3 4 import os,sys 5 6 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 7 sys.path.append(BASE_DIR) 8 9 from foo import main 10 11 12 13 menu_dict = { 14 '信用卡中心': ['0:我的信用卡', 15 '1:提现', 16 '2:转账', 17 '3:还款', 18 'q:返回'], 19 '后台管理': ['4:创建用户', 20 '5:删除用户', 21 'q:返回'], 22 '输入q:退出': ''} 23 24 25 msg = ''' 26 1:注册账号 27 2:商城购物 28 q:返回 29 ''' 30 31 sp_dict = { 32 '1':main.sp_add, 33 '2':main.shopping, 34 }
main.py
主功能程序
1 #!/usr/bin/python env 2 # _*_ encoding:utf-8 _*_ 3 import os,sys,time,json 4 5 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 6 sys.path.append(BASE_DIR) 7 8 from foo import file_dir 9 from foo import index 10 11 12 13 #信用卡认证用户密码 14 def auth(func): 15 index = input("1.信用卡中心 2.购物商城:") 16 if index =='2': 17 sp_index() 18 if index == '1': 19 def wrapper(*args,**ksargs): 20 data=file_dir.get_user_data() 21 time_formate = '%Y-%m-%d %X ' 22 start_time = time.strftime(time_formate,time.localtime()) 23 count = 0 24 while count < 3: 25 global username 26 username = input("\033[32m请输入用户名:>>\033[0m:") 27 passwd = input("\033[35m请输入密码:>>\033[0m") 28 file_dir.sd(username) 29 if username in data and passwd == data[username]['Password']: 30 print("\033[32m#############################\033[0m") 31 print("\033[31m欢迎{0}登录\033[0m".format(username)) 32 print("\033[32m#############################\033[0m") 33 login = start_time+'用户%s登录成功!\n' % username 34 file_dir.login_log(login) 35 func() 36 count += 1 37 if count == 3: 38 log_sd = start_time + '用户%s已锁定\n' % username 39 file_dir.locking(log_sd) 40 print("\033[36m密码错误次数过多,用户已经锁定!请联系管理员.\033[0m") 41 else: 42 print("\033[31m用户名或密码错误\033[0m") 43 error = start_time + '用户%s登录失败!\n' % username 44 file_dir.error_log(error) 45 return wrapper 46 47 48 #商城购物认证信用卡用户密码 49 def wr(): 50 data=file_dir.get_user_data() 51 time_formate = '%Y-%m-%d %X ' 52 start_time = time.strftime(time_formate,time.localtime()) 53 count = 0 54 while count < 3: 55 global usernam 56 usernam = input("\033[32m请输入用户名:>>\033[0m:") 57 passwd = input("\033[35m请输入密码:>>\033[0m") 58 file_dir.sd(usernam) 59 if usernam in data and passwd == data[usernam]['Password']: 60 print("\033[32m#############################\033[0m") 61 print("\033[31m欢迎{0}登录\033[0m".format(usernam)) 62 print("\033[32m#############################\033[0m") 63 login = start_time+'用户%s登录成功!\n' % usernam 64 file_dir.login_log(login) 65 return 66 count += 1 67 if count == 3: 68 log_sd = start_time + '用户%s已锁定\n' % usernam 69 file_dir.locking(log_sd) 70 print("\033[36m密码错误次数过多,用户已经锁定!请联系管理员.\033[0m") 71 else: 72 print("\033[31m用户名或密码错误\033[0m") 73 error = start_time + '用户%s登录失败!\n' % usernam 74 file_dir.error_log(error) 75 76 77 #商城购物减钱 78 def sp_m(dat): 79 while True: 80 time_formate = "%Y-%m-%d %X " 81 start_time = time.strftime(time_formate,time.localtime()) 82 data = file_dir.get_user_data() 83 user = input("1.确认 2.返回:") 84 if user == '1': 85 if dat <= data[usernam]['Credit']: 86 data[usernam]['Credit'] -= dat 87 data[usernam]['Balance'] += dat 88 file_dir.add_user(data) 89 data_log = start_time + usernam +"消费成功\n" 90 file_dir.atm_log(data_log) 91 print("购物消费%s"%dat) 92 return 93 else: 94 print("你输入的金额超出了总额度!") 95 exit() 96 else: 97 exit() 98 99 100 101 102 103 #打印购物菜单 104 def sp_index(): 105 while True: 106 print(index.msg) 107 users = input("请选择:>>") 108 if users.isdigit(): 109 user = int(users) 110 index.sp_dict[users]() 111 if users == 'q': 112 exit() 113 114 #创建购物用户 115 def sp_add(): 116 while True: 117 p_user =input("请输入注册账号:") 118 data = file_dir.user_r(sp_user) 119 if data == False: 120 sp_pwd = input("请输入密码:") 121 sp_passwd = input("请再次输入密码:") 122 if sp_pwd == sp_passwd: 123 sp_data = "%s %s\n" % (p_user,sp_passwd) 124 file_dir.user_w(sp_data) 125 print("用户{0}创建成功!".format(p_user)) 126 return sp_add 127 else: 128 print("两次密码输入不一致!") 129 130 else: 131 print("你输入的用户已存在!") 132 break 133 134 135 #购物商城认证用户密码 136 def sp_auth(func): 137 def wr(*args,**kwargs): 138 while True: 139 global sp_user 140 sp_user = input("请输入购物账号:") 141 pawd = input("请输入要密码:") 142 f = open(BASE_DIR + '\databases\\sp_user','r') 143 f2 = f.readlines() 144 f.close() 145 for i in f2: 146 (name,pas) = i.strip('\n').split() 147 if sp_user == name and pawd == pas: 148 print("欢迎登陆 购物商城") 149 func() 150 else: 151 print("密码或用户名不正确") 152 break 153 return wr 154 155 156 #购物商城主程序 157 @sp_auth 158 def shopping(): 159 tag = True 160 splist = [] 161 shopping_list = [ 162 ['Iphone 6s plus', 5800], 163 ['Lumia', 3800], 164 ['Charge', 45], 165 ['Data line', 35], 166 ['MI 5 PRO', 2299], 167 ['MX4', 1999],] 168 169 while tag: 170 user_sp = input("1.购物 2.查看购物历史 3.退出") 171 if user_sp == '3': 172 exit() 173 if user_sp == '2': 174 with open(BASE_DIR + '\logs\\shopping_log', 'r', encoding='utf-8') as f: 175 for i in f: 176 if sp_user in i: 177 print(i.strip('\n')) 178 if user_sp == '1': 179 for k,v in enumerate(shopping_list): 180 print(k,v) 181 user_s = input("请选择商品:") 182 if user_s.isdigit(): 183 user_s = int(user_s) 184 if user_s <= len(shopping_list): 185 shopping_list.append(user_s) 186 user_f = input("1.购物结算 2.查看购物车 3.返回") 187 if user_f == '3': 188 break 189 if user_f == '2': 190 for i in shopping_list: 191 print(i) 192 break 193 if user_f == '1': 194 sp = shopping_list[user_s][1] 195 print("欢迎进入信用卡系统中心") 196 wr() 197 sp_m(sp) 198 print("你已成功购买%s"%shopping_list[user_s]) 199 time_formate = "%Y-%m-%d %X " 200 start_time = time.strftime(time_formate, time.localtime()) 201 log = start_time + sp_user + " 成功购买%s\n" % shopping_list[user_s] 202 file_dir.sp_log(log) 203 204 205 206 207 208 #查询信用卡信息 209 def mycc(): 210 while True: 211 data = file_dir.get_user_data() 212 id = input("请输入要查询的账号:") 213 pwd= input("请输入密码:") 214 for i in data: 215 if username in i: 216 if id == data[username]['User_id'] and pwd == data[username]['Password']: 217 dy = "你的总额度:%s,还款:%s" %(data[username]['Credit'],data[username]['Balance']) 218 print(dy) 219 return 220 else: 221 print("你输入的账号或密码不正确!") 222 continue 223 224 225 #信用卡取款 226 def money(): 227 while True: 228 time_formate = "%Y-%m-%d %X " 229 start_time = time.strftime(time_formate,time.localtime()) 230 data = file_dir.get_user_data() 231 print("你的当余额为:%s" % data[username]['Credit']) 232 user_m = input("请输入你的取款金额") 233 user = input("1.确认 2.返回:") 234 if user == '1': 235 if user_m.isdigit(): 236 user_m = int(user_m) 237 if user_m <= data[username]['Credit']: 238 data[username]['Credit'] -= user_m 239 data[username]['Balance'] += user_m 240 file_dir.add_user(data) 241 print(username + "已经成功取款:%s,你的余额为:%s"%(user_m,data[username]['Credit'])) 242 data_log = start_time + username +"成功取款\n" 243 file_dir.atm_log(data_log) 244 return money 245 else: 246 print("你输入的金额超出了总额度!") 247 248 else: 249 break 250 251 252 253 254 255 #信用卡转账 256 def Transfer_accounts(): 257 data = file_dir.get_user_data() 258 time_formate = "%Y-%m-%d %X " 259 start_time = time.strftime(time_formate,time.localtime()) 260 while True: 261 print("你的当前总额度为:%s" % data[username]['Credit']) 262 name = input("请输入对方用户名:") 263 for i in data: 264 if name in i: 265 user_m = input("请输入转账金额:") 266 if user_m.isdigit(): 267 user_m = int(user_m) 268 if user_m <= data[username]['Credit']: 269 passwd = input("请输入密码:") 270 if passwd == data[username]['Password']: 271 use= input("1.确认 2.返回:") 272 if use == '1': 273 data[username]['Credit'] -= user_m 274 data[username]['Balance'] += user_m 275 data[name]['Credit'] += user_m 276 file_dir.add_user(data) 277 print("%s用户成功转账给%s用户%s圆"%(username,name,user_m)) 278 print("你的当前总额度为:%s" % data[username]['Credit']) 279 log = start_time + "%s用户成功转账给%s用户%s圆\n" % (username,name,user_m) 280 file_dir.atm_log(log) 281 return Transfer_accounts 282 else: 283 exit() 284 else: 285 print("密码输入错误!") 286 break 287 else: 288 print("你输入的余额超出了你的总额范围!") 289 break 290 else: 291 print("你输入的用户名不存在!") 292 break 293 294 295 296 297 #信用卡还款 298 def repayment(): 299 while True: 300 data = file_dir.get_user_data() 301 time_formate = "%Y-%m-%d %X " 302 start_time = time.strftime(time_formate,time.localtime()) 303 print("你还需还款:%s" %data[username]['Balance']) 304 user_m = input("请输入还款金额:") 305 if user_m.isdigit(): 306 user_m = int(user_m) 307 if user_m <= data[username]['Balance']: 308 user = input("1.确认,2.返回:") 309 if user == '1': 310 data[username]['Balance'] -= user_m 311 data[username]['Credit'] += user_m 312 print("你已成功还款%s"%user_m) 313 print("还需要还款:%s你的总额度为:%s" %(data[username]['Balance'],data[username]['Credit'])) 314 file_dir.add_user(data) 315 log = start_time + "%s用户成功还款%s\n" %(username,user_m) 316 file_dir.atm_log(log) 317 return repayment 318 else: 319 break 320 else: 321 print("你输入的余额超出了还款范围!") 322 break 323 else: 324 print("你的输入有误!") 325 break 326 327 328 #创建信用卡用户 329 def create_user(): 330 while True: 331 if username != "admin": 332 print("\033[34m权限不足!\033[0m") 333 user_id = input("请输入卡号:") 334 if len(user_id) != 3: 335 print("你输入的卡号不满足3位数字!") 336 continue 337 credit = input("请输入额度:") 338 if user_id.isdigit() and credit.isdigit(): 339 user_id = int(user_id) 340 credit=int(credit) 341 use = input("请输入登录用户名:") 342 passwd_1=input("请输入密码:") 343 passwd_2=input("请再次输入密码:") 344 if passwd_2 != passwd_1: 345 print("你输入的密码不一致!") 346 continue 347 use_2 = input("1.确认,2.取消") 348 if use_2 == '1': 349 user_data = file_dir.get_user_data() 350 user_data[use] = {'Name':use,'Password':passwd_2,'Credit':credit,'Balance':0,'User_id':user_id} 351 #print(user_data[use]) 352 file_dir.add_user(user_data) 353 print("用户添加成功!") 354 return create_user 355 else: 356 continue 357 358 359 360 #删除信用卡用户 361 def del_user(): 362 while True: 363 data = file_dir.get_user_data() 364 if username != "admin": 365 print("你没有权限删除用户!") 366 exit() 367 user = input("请输入要删除的用户:") 368 for i in data: 369 if user in i: 370 usedel = input("1.确证 2.取消:") 371 if usedel == '1': 372 data.pop(user) 373 file_dir.add_user(data) 374 print("删除成功!") 375 return del_user 376 else: 377 exit() 378 else: 379 print("你输入的用户不存在!") 380 break
atm
ATM操作日志
1 2017-04-24 13:33:14 成功取款 2 2017-04-24 14:00:58 成功取款 3 2017-04-24 14:06:01 成功取款 4 2017-04-24 14:09:02 成功取款 5 2017-04-24 14:10:23 han成功取款 6 2017-04-24 15:53:29 admin用户成功还款 7 02017-04-24 15:56:07 han用户成功还款3000 8 2017-04-24 19:33:16 admin用户成功转账给han用户500圆 9 2017-04-24 19:40:31 han用户成功转账给admin用户500圆 10 2017-04-25 20:36:15 admin购物消费 11 2017-04-25 20:52:39 admin消费成功 12 2017-04-25 21:08:08 admin消费成功 13 2017-04-25 21:10:06 han消费成功 14 2017-04-26 13:32:52 admin消费成功
errorlog
ATM错误日志
1 2017-19-04 15:20:13 用户admin登录失败! 2 2017-19-04 15:20:13 用户admin登录失败! 3 2017-19-04 15:50:53 用户admin登录失败! 4 2017-19-04 15:50:53 用户admin登录失败!
shoping_log
购物历史文件
1 2017-04-25 20:52:20 han成功购买['Lumia', 3800] 2 2017-04-25 20:52:40 han成功购买['Charge', 45]
login
ATM登陆日志
1 2017-19-04 15:20:13 用户admin登录成功! 2 2017-19-04 19:32:03 用户admin登录成功! 3 2017-19-04 19:33:34 用户admin登录成功! 4 2017-19-04 19:34:43 用户admin登录成功! 5 2017-19-04 19:39:22 用户admin登录成功! 6 2017-19-04 19:42:43 用户admin登录成功! 7 2017-19-04 19:42:57 用户admin登录成功!
README.txt
使用帮助说明文件
1 ATM程序目录介绍 2 3 ATM 4 bin 5 creditcard.py 启动程序 6 7 conf 8 locking 信用卡锁定用户文件 9 10 databases 11 admin 信用卡用户密码文件 12 sp_user 购物商城用户密码文件 13 14 docs 空 15 16 foo 17 test 空 18 file_dir.py 文件处理程序 19 index.py 主页菜单程序 20 main.py 主功能程序 21 22 logs 23 atm ATM操作日志 24 errorlohg ATM错误日志 25 login ATM登陆日志 26 shopping_log 购物历史文件 27 28 README.txt 使用帮助说明文件 29 30 requirements.txt 空 31 32 33 34 ATM程序使用说明 35 1.启动creditcard.py程序 36 2.选择服务 37 3.信用卡默认账号密码为:admin 789 38 4.只有admin用户才可以注册ATM账号 39 40 商城购物使用说明 41 1.购物前需要先注册账号密码 42 2.购物结账调用信用卡账号密码 43 3.结账直接在信用内扣除余额
requirements.txt
空
1 kong
time(时间模块)
import time
python2.0
print(time.process_time()) #返回处理器时间
python3.0
print(time.clock()) #返回处理器时间
print(time.gmtime(time.time()-800000)) #返回utc时间的struc时间对象格式
print(time.ctime()) #返回本地之间 Fri May 5 14:25:46 2017
print(time.altzone) #返回utc时间的时间差,以秒计算
print(time.localtime()) #返回时间对象
打印指定的对象
t = time.localtime()
print(t)
print(t.tm_year, t.tm_yday)
print(time.time() / (3600 * 24 * 365))
打印三个小时后的时间
t = time.localtime(time.time() + 3600 * 3)
print(t)
转换为时间戳
t2 = time.strptime("2017-11-11 23:30", "%Y-%m-%d %H:%M")
print(time.mktime(t2))
时间戳转换
t2_stamp = time.mktime(t2)
t3 = time.localtime(t2_stamp)
t3_str = time.strftime("%Y_%m_%d.log", t3)
print(t3_str)
import datetime
时间戳直接转成日期格式2017-05-05 print(datetime.date.fromtimestamp(time.time())) 返回 2016-08-19 12:47:03.941925 print(datetime.datetime.now()) 修改指定的时间 now = datetime.datetime.now() print(now.replace(month=1,day=1)) 当前时间+3天 print(datetime.datetime.now() + datetime.timedelta(3)) 当前时间-3天 print(datetime.datetime.now() + datetime.timedelta(-3)) 当前时间+3小时 print(datetime.datetime.now() + datetime.timedelta(hours=3)) 当前时间+30分钟 print(datetime.datetime.now() + datetime.timedelta(minutes=30))
random
print(random.randint(1,5))
随机数
checkcode = ' '
for i in range(4):
current = random.randrange(0,4)
if current !=i:
temp = chr(random.randint(65,90))
else:
temp = random.randint(0,9)
checkcode += str(temp)
print(checkcode)
import json,pickle
json 支持跨语言,pikle 支持复杂类型
pikle序列化
data = {'k1': 123, 'k2': 'hell'}
with open(r'D:/result.pk', 'wb') as fp:
pickle.dump(data, fp)
pikle反序列化
with open(r'D:/result.pk', 'rb') as fp2:
a = pickle.load(fp2)
print(a
json序列化
with open(r'D:/result.pk','w') as fj:
json.dump(data,fj)
json反序列化
with open(r'D:/result.pk','r') as fj2:
a=json.load(fj2)
print(a)
shutil
import shutil
复制文件
shutil.copy(r'D:/result.pk','D:/result.txt')
打包目录(打包只打包不压缩)
ret = shutil.make_archive('D:/han','gztar',root_dir = 'C:/temp')
zip压缩
import zipfile
z = zipfile.ZipFile('D:/han.zip','w')
z.write('C:/temp.txt')
z.close()
zip解压
z = zipfile.ZipFile('D:/han.zip','r')
z.extractall('D:/')
z.close
tar压缩 (tar可以压缩目录和文件)
import tarfile
tar = tarfile.open('D:/han.tar','w')
tar.add('C:/temp.txt',arcname = 'temp.txt' )
tar.close()
tar解压
tar = tarfile.open('D:/han.tar','r')
tar.extractall('D:/')
tar.close()
shelve
shelve 可以对此dump数据,pikle和json只可以dump一次
import shelve
file1
d = shelve.open('shelve_test')
def stu_data(name,age):
print("register stu",name,age)
name = ['alex','rain','test']
info = {'name':'alex','age':22}
d['test'] = name 添加
d['info'] = info
d['func'] = stu_data
file2
import shelve
def stu_data(name,age):
print(name,age)
f = shelve.open("shelve_test") 打开文件
print(f['test']) 打印
print(f['info'])
print(f['func']('zhang',22))
xml
xml,file格式
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
import xml.etree.ElementTree as ET
打印根
tree = ET.parse("xmltest.xml")
root = tree.getroot()
print(root.tag)
递归打印
for child in root:
print(child.tag,child.attrib) #打印根和值
for i in child:
print('\t',i.tag,i.attrib,i.text) #打印值和属性
print('\t', i.tag,i.text)
筛选打印
for node in root.iter('year'):
print(node.tag,node.text)
for child in root:
print(child.tag,child.attrib)
for i in child.iter("year"):
print("\t",i.tag,i.attrib,i.text)
修改
for node in root.iter('year'):
new_year = int(node.text) + 1
node.text = str(new_year)
node.set('updated','yes')
tree.write('xmltest.xml')
删除
for country in root.findall('country'):
rank = int(country.find('rank').text)
if rank > 50:
root.remove(country)
tree.write('output.xml')
创建xml文件
from xml.etree import ElementTree as ET
from xml.dom import minidom
def prettify(elem): #处理换行函数
rough_string = ET.tostring(elem,'utf-8')
reparsed = minidom.parseString(rough_string) #分割
return reparsed.toprettyxml(indent='\t') #换行
root = ET.Element('famliy') #根名
son1 = root.makeelement('son',{'name':'erzi1'}) #创建子
son2 = root.makeelement('son',{'name':'erzi2'}) #创建子
grandson1 = son1.makeelement('grandson',{'name':'sunzi1'}) #创建子子
grandson2 = son1.makeelement('grandson',{'name':'sunzi2'}) #创建子子
son1.append(grandson1) #添加
son2.append(grandson2)
root.append(son1) #添加
root.append(son2)
raw_str = prettify(root) #传给处理函数
f = open('test6.xml','w',encoding='utf-8') #打开i文件
f.write(raw_str) #写入文件
f.close()
configtarser
生成配置文件
import configparser
config = configparser.ConfigParser()
config["DEFAULT"] = {'ServerAliveInterval':'45', #创建全局配置
'Compression':'yes',
'CompressionLevel':'9'}
config['bitbucket.org'] = {} #创建标题
config['bitbucket.org']['User'] = 'hg' #创建
config['topsecret.server.com'] = {} #创建标题
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022' #创建
topsecret['ForwardX11'] = 'no'
config['DEFAULT']['ForwardX11'] = 'yes' #创建
with open('example.ini', 'w') as configfile: #打开文件
config.write(configfile) #写入文件
生成后的文件
[DEFAULT]
serveraliveinterval = 45
compression = yes
compressionlevel = 9
forwardx11 = yes
[bitbucket.org]
user = hg
[topsecret.server.com]
host port = 50022
forwardx11 = no
打印
import configparser
config = configparser.ConfigParser()
config.read('example.ini')
print(config.sections()) #打印标题下的所有内容
print(config.defaults())
print('bitbucket.org' in config)
print(config['bitbucket.org']['user']) #打印标题下制定的
print(config['topsecret.server.com']['host port'])
打印标题下制定的
a = config.sections()[1]
print(config[a]['host port'])
打印制定标题下
for key in config['bitbucket.org']:
print(key )
打印制定标题下key,valuer
for k in config['topsecret.server.com']:
print(k,config['topsecret.server.com'][k])
import configparser
config = configparser.ConfigParser()
config.read('i.cfg') #打开文件
secs = config.sections() #取组名1
options = config.options('section2') #取组名2
print(options) #打印k
打印k和v
item_list = config.items('section2')
print(item_list)
打印values
val = config.get('section1','k1')
print(val)
获取values 是否是数字
val2 = config.getint('section2','k2')
print(val2)
判断节点是否存在不存在创建
sec = config.has_section('wupeiqi')
sec = config.add_section('wupeiqi')
config.write(open('i.cfg','w'))
删除组
sec = config.remove_section('section2')
config.write(open('i.cfg','w'))
存在修改 不存在添加
config.set('section2','k2','66')
config.write(open('i.cfg','w'))
删除
config.remove_option('section2','k5')
config.write(open('i.cfg','w'))
hashlib
用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
import hashlib md5 hash = hashlib.md5() hash.update(b'admin') print(hash.hexdigest()) sha1 hash = hashlib.sha1() hash.update(b'admin') print(hash.hexdigest()) print(hash.digest()) sha256 hash = hashlib.sha256() hash.update(b'admin') print(hash.hexdigest()) sha384 hash = hashlib.sha384() hash.update(b'admin') print(hash.hexdigest()) sha512 hash = hashlib.sha512() hash.update(b'admin') print(hash.hexdigest())
还不够吊?python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密
散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。使用HMAC时,消息通讯的双方,通过验证消息中加入的鉴别密钥K来鉴别消息的真伪;
一般用于网络通信中消息加密,前提是双方先要约定好key,就像接头暗号一样,然后消息发送把用key把消息加密,接收方用key + 消息明文再加密,拿加密后的值 跟 发送者的相对比是否相等,这样就能验证消息的真实性,及发送者的合法性了。
hmac
import hmac h = hmac.new(b'password',b'username') print(h.hexdigest())
import logging
打印
logger = logging.getLogger('TEST-LOG') #名称
logger.setLevel(logging.INFO) #定义全局级别
ch=logging.StreamHandler() #打印屏幕
ch.setLevel(logging.DEBUG) #定义局部级别
format = logging.Formatter('%(asctime)s - %(filename)s - %(levelname)s - %(message)s',datefmt='%Y-%m-%d %I:%S %p') #定义打印格式
ch.setFormatter(format) #添加格式
logger.addHandler(ch) #添加
logger.debug('This message shouid go to then log file') #定义打印内容
logger.info('S should this') #定义打印内容
logger.warning('And this too') #定义打印内容
看一下这几个日志级别分别代表什么意思
| Level | When it’s used |
|---|---|
DEBUG |
Detailed information, typically of interest only when diagnosing problems. |
INFO |
Confirmation that things are working as expected. |
WARNING |
An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected. |
ERROR |
Due to a more serious problem, the software has not been able to perform some function. |
CRITICAL |
A serious error, indicating that the program itself may be unable to continue running. |
打印屏幕有写入文件
import logging
logger = logging.getLogger('TEST-LOG') #定义名称
logger.setLevel(logging.INFO) #定义全局级别
ch = logging.StreamHandler() #打印屏幕
ch.setLevel(logging.DEBUG) #定义局部级别
fh = logging.FileHandler("access.log") #写入文件1
fh.setLevel(logging.WARNING) #定义局部级别
fh_err = logging.FileHandler("error.log") #写入文件2
fh_err.setLevel(logging.ERROR) #定义局部级别
formatter = logging.Formatter('%(asctime)s - %(filename)s - %(levelname)s - %(message)s'
,datefmt='%Y-%m-%d %I:%S %p') #打印格式
formatter_for_file = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %I:%S %p') #打印格式
ch.setFormatter(formatter) #添加格式
fh.setFormatter(formatter_for_file) #添加格式
fh_err.setFormatter(formatter) #添加格式
logger.addHandler(ch) #添加
logger.addHandler(fh)
logger.addHandler(fh_err)
logger.debug('debug message') #打印内容
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
日志格式
|
%(name)s |
Logger的名字 |
|
%(levelno)s |
数字形式的日志级别 |
|
%(levelname)s |
文本形式的日志级别 |
|
%(pathname)s |
调用日志输出函数的模块的完整路径名,可能没有 |
|
%(filename)s |
调用日志输出函数的模块的文件名 |
|
%(module)s |
调用日志输出函数的模块名 |
|
%(funcName)s |
调用日志输出函数的函数名 |
|
%(lineno)d |
调用日志输出函数的语句所在的代码行 |
|
%(created)f |
当前时间,用UNIX标准的表示时间的浮 点数表示 |
|
%(relativeCreated)d |
输出日志信息时的,自Logger创建以 来的毫秒数 |
|
%(asctime)s |
字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 |
|
%(thread)d |
线程ID。可能没有 |
|
%(threadName)s |
线程名。可能没有 |
|
%(process)d |
进程ID。可能没有 |
|
%(message)s |
用户输出的消息 |
日志切割
import logging
from logging import handlers
logger = logging.getLogger(__name__) #定义名称
logger.setLevel(logging.ERROR) #定义全局级别
log_file = "timelog.log" #文件
fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=5,backupCount=3) #日志最大5个字节,最大生成3个
#fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=2,backupCount=3)#没两秒生成一个日志最大3个
formatter = logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s'
,datefmt='%Y-%m-%d %I:%S %p') #定义打印格式
fh.setFormatter(formatter) #添加格式
logger.addHandler(fh) #添加
logger.debug('debug message') #打印内容
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
常用正则表达式符号
. 默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
^ 匹配字符开头
$ 匹配字符结尾
* 匹配前面的字符0次或多次
+ 匹配前面的字符1次或多次
? 匹配一个字符1次或0次
{m} 匹配前一个字符m次
{m,n} 匹配前一个字符m次到n次
| 匹配或者
(...) 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c
\A 只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的
\Z 匹配字符结尾,同$
\d 匹配字符0-9
\D 匹配非数字
\w 匹配[0-9a-z]
\W 匹配非[0-9a-z]
s 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
(?P<name>...) 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}
最长用的匹配语法
re.match 从头开始匹配 re.search 匹配包含 re.findall 匹配包含的所有 re.splitall 以匹配到的字符做列表分隔符 re.sub 匹配字符并替换 re.subn 匹配替换并显示替换了几个 re.split 匹配分割
a=re.findall("alex",'alexdfgdfgdfgdfgdfgdfg')
b=re.findall('al.*','alexdfgdfgdfgdfgdfgdfg')
c=re.findall('al.+x','alexdfgdfgdfgdfgdfgdfg')
d=re.findall('al.?x','alexdfgdfgdfgdfgdfgdfg')
e=re.findall('al.{1,5}x','alexdfgdfgdfgdfgdfgdfg')
f=re.findall('al.[bc]x','albcxdfgdfgdfgdfgdfgdfg')
g=re.findall('al.[a-z]x','albcxdfgdfgdfgdfgdfgdfg')
h=re.findall('a[a-z]+d','agbd')
i=re.findall('a[a*]','a*d')
j=re.findall('a[^f]d','a*d')
k=re.findall('a[\d]d','a2d')
bb=re.match('com','comwwww.runcomoob')
print(bb.span())
print(bb.group())
cc=re.search('com','comwwww.runcomoob')
print(cc)
print(cc.group())
ww=re.search(r'\\','www.run\comoob')
w=re.search(r'(\d{1,3}\.){3}\d{1,3}','asds 192.168.6.6')
print(w.group())
print(ww.group())
ee=re.subn('com','COM','comwwww.runcomoob')
print(ee)
test='asdasdasdasdooasdasdasd'
regex = re.compile(r'\w*oo\w*')
print(regex.findall(test))
origin = 'hasaabc dfoujqwi halaabc m098u29841'
r = re.match('h\w+',origin)
print(r.group())
分组
ff=re.match('h(?P<name>\w+)+',origin)
print(ff.groupdict())
w2=re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})", "371481199306143242").groupdict("city")
print(w2)
用匹配到的之当作values分开
fff = re.findall ('h(\w+)a(ab)c',origin)
print(fff)
分割
origin1='hello alex bcd alex lge alex acd 19'
r1=re.split('a(le)x',origin1,1)
print(r1)
反斜杠的困扰
与大多数编程语言相同,正则表达式里使用"\"作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"\",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\\"表示。同样,匹配一个数字的"\\d"可以写成r"\d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。
仅需轻轻知道的几个匹配模式
re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同) M(MULTILINE): 多行模式,改变'^'和'$'的行为(参见上图) S(DOTALL): 点任意匹配模式,改变'.'的行为
计算当输入下列数字计算出结果
-1-2*(-60+30+(-40/5)*(-9-2*-5/30-7/3*99/4*2998+10/-568/14))-(-4*-3)/(16-3*2)+3
流程图
1 #!/usr/bin/python env 2 # _*_ encoding:utf-8 _*_ 3 4 import re 5 6 #1.分割字符串 7 def init_action(expression): 8 expression=re.sub(' ','',expression) #去除空格 9 init_l=[i for i in re.split( '(\-\d+\.*\d*)',expression) if i] #按-1数字分割 10 expression_l=[] 11 while True: 12 if len(init_l) == 0:break 13 exp=init_l.pop(0) 14 if len(expression_l) == 0 and re.search('^\-\d+\.*\d*$',exp): #-1开头或结尾的不分割,添加到列表 15 expression_l.append(exp) 16 continue 17 if len(expression_l) > 0: 18 if re.search('[\+\-\*\/\(]$',expression_l[-1]): #+,*,/,-1结尾的不分割,添加到列表 19 expression_l.append(exp) 20 continue 21 new_l=[i for i in re.split('([\+\-\*\/\(\)])',exp) if i] #分割 22 expression_l+=new_l 23 24 return expression_l 25 26 27 #2.主函数 28 def main(expression): 29 number_stack=[] 30 symbol_stack=[] 31 for ele in expression: 32 print('------------') 33 print('数字栈',number_stack) 34 print('运算符栈',symbol_stack) 35 print('待入站符',ele) 36 ret=is_symbol(ele) #传给判断字符运算符函数 37 if not ret: #如果不是运算符 38 ele=float(ele) 39 number_stack.append(ele) 40 else: #如果是运算符 41 while True: 42 if len(symbol_stack) == 0: #如果运算符列表为空 43 symbol_stack.append(ele) #添加运算符列表 44 break 45 res=priority(symbol_stack[-1],ele) #判断运算符列表最后一个运算符和即将入栈的运算符的优先级 46 if res == '<': 47 symbol_stack.append(ele) 48 break 49 elif res == '=': 50 symbol_stack.pop() #当左括号遇到右括号直接删除 51 break 52 elif res == '>': 53 symbol=symbol_stack.pop() #取出运算符 54 num2=number_stack.pop() #取出数字1 55 num1=number_stack.pop() #取出数字2 56 number_stack.append(calculate(num1,symbol,num2)) #传给计算函数 57 else: #当循环结束遇到括号外最后一个数字 58 symbol = symbol_stack.pop() 59 num2 = number_stack.pop() 60 num1 = number_stack.pop() 61 number_stack.append(calculate(num1,symbol,num2)) #传给计算函数 62 63 return number_stack,symbol_stack 64 65 66 #3.判断是数字还是运算符 67 def is_symbol(element): 68 ret=False 69 symbol=['+','-','*','/','(',')'] 70 if element in symbol: 71 ret=True #如果是运算符返回True 72 73 return ret 74 75 #4.判断运算符的优先级 76 def priority(top_sym,wait_sym): 77 level1=['+','-'] 78 level2=['*','/'] 79 level3=['('] 80 level4=[')'] 81 if top_sym in level1: #当栈顶运算符是+|- 82 # if wait_sym in level1: #当入栈运算符是+|- 83 # return '>' 84 # elif wait_sym in level2: 当入栈运算符是*|/ 85 # return '<' 86 # elif wait_sym in level3: 87 # return '<' 88 # elif wait_sym in level4: 89 # return '>' 90 if wait_sym in level2 or wait_sym in level3: #优化 91 return '<' 92 else: 93 return '>' 94 elif top_sym in level2: #当栈顶运算符是*|/ 95 if wait_sym in level3: #优化 96 return '<' 97 else: 98 return '>' 99 elif top_sym in level3: #优化 100 if wait_sym in level4: 101 return '=' 102 else: 103 return '<' 104 105 #5.计算 106 def calculate(num1,symbol,num2): 107 res=0 108 if symbol == '+': #如果运算符是+ 让数字1+数字2 109 res=num1+num2 110 elif symbol == '-': #如果运算符是- 让数字1-数字2 111 res=num1-num2 112 elif symbol == '*': 113 res=num1*num2 114 elif symbol == '/': 115 res=num1/num2 116 print('----> %s,%s,%s,%s'% (num1,symbol,num2,res)) 117 return res 118 119 120 if __name__ == '__main__': 121 expression='-1 - 2 *((-60+30+(-40/5)*(-9-2*-5/30-7/3*99/4*2998+10/-568/14))-(-4*-3)/(16-3*2))+3' 122 expression_l=init_action(expression) 123 l=main(expression_l) 124 print(l) 125 print(l[0][0])
员工信息表
#_*_coding:utf-8_*_
#第一部分:sql解析
import os
def sql_parse(sql):
'''
sql_parse--->insert_parse,delete_parse,update_parse,select_parse
sql解析总控
:param sql:用户输入的字符串
:return: 返回字典格式sql解析结果
'''''
parse_func={
'insert':insert_parse,
'delete':delete_parse,
'update':update_parse,
'select':select_parse,
}
sql_l=sql.split(' ')
func=sql_l[0]
res=''
if func in parse_func:
res=parse_func[func](sql_l)
return res
def insert_parse(sql_l):
# insert into db.t1 values 鲁海宝,35,13910015353,测试,2005-06-27
'''
sql解析分支:insert
:param sql_l: sql按照空格分割的列表
:return: 返回字典格式的sql解析结果
'''''
sql_dic={
'func':insert, #函数名
'insert':[], #insert选项,留出扩展
'into':[], #表名
'values':[], #值
}
return handle_parse(sql_l,sql_dic)
def delete_parse(sql_l):
# delete from db.t1 where id=1
'''
sql解析分支:delete
:param sql_l: sql按照空格分割的列表
:return: 返回字典格式的sql解析结果
'''''
sql_dic={
'func':delete,
'delete':[], #delete选项,留出扩展
'from':[], #表名
'where':[], #filter条件
}
return handle_parse(sql_l,sql_dic)
def update_parse(sql_l):
# update db.t1 set id=2 where name='alex'
'''
sql解析分支:update
:param sql_l: sql按照空格分割的列表
:return: 返回字典格式的sql解析结果
'''''
sql_dic={
'func':update,
'update':[], #update选项,留出扩展
'set':[], #修改的值
'where':[], #filter条件
}
return handle_parse(sql_l,sql_dic)
def select_parse(sql_l):
# select * from db1.emp where not id= 1 and name = 'alex' or name= 'sb' limit 3
'''
sql解析分支:select
:param sql_l: sql按照空格分割的列表
:return: 返回字典格式的sql解析结果
'''''
sql_dic={
'func':select,
'select':[], #查询字段
'from':[], #表
'where':[], #filter条件
'limit':[], #limit条件
}
return handle_parse(sql_l,sql_dic)
def handle_parse(sql_l,sql_dic):
'''
填充sql_dic
:param sql_l: sql按照空格分割的列表
:param sql_dic: 待填充的字典
:return: 返回字典格式的sql解析结果
'''''
tag=False
for item in sql_l:
if tag and item in sql_dic:
tag=False
if not tag and item in sql_dic:
tag=True
key=item
continue
if tag:
sql_dic[key].append(item)
# print('before \033[33;1m%s\033[0m' %sql_dic)
if sql_dic.get('where'):
sql_dic['where']=where_parse(sql_dic.get('where'))
# print('after \033[33;1m%s\033[0m' %sql_dic)
return sql_dic
def where_parse(where_l):
'''
对用户输入的where子句后的条件格式化,每个子条件都改成列表形式
:param where_l: 用户输入where后对应的过滤条件列表
:return:
'''''
res=[]
key=['and','or','not']
char=''
for i in where_l:
if len(i) == 0:continue
if i in key:
if len(char) != 0:
char=three_parse(char) #将每一个小的过滤条件如,name>=1转换成['name','>=','1']
res.append(char)
res.append(i)
char=''
else:
char+=i
else:
char=three_parse(char)
res.append(char)
return res
def three_parse(exp_str):
'''
将每一个小的过滤条件如,name>=1转换成['name','>=','1']
:param exp_str:条件表达式的字符串形式,例如'name>=1'
:return:
'''''
# print('three_opt before is \033[34;1m%s\033[0m' %exp_str)
key=['>','=','<']
res=[]
char=''
opt=''
tag=False
for i in exp_str:
if i in key:
tag=True
if len(char) !=0:
res.append(char)
char=''
opt+=i
if not tag:
char+=i
if tag and i not in key:
tag=False
res.append(opt)
opt=''
char+=i
else:
res.append(char)
# print('res is %s ' %res)
#新增like功能
if len(res) == 1:#['namelike_ale5']
res=res[0].split('like')
res.insert(1,'like')
return res
#第二部分:sql执行
def sql_action(sql_dic):
'''
执行sql的统一接口,内部执行细节对用户完全透明
:param sql:
:return:
'''''
return sql_dic.get('func')(sql_dic)
def insert(sql_dic):
print('insert %s' %sql_dic)
db,table=sql_dic.get('into')[0].split('.')
with open('%s/%s' %(db,table),'ab+') as fh:
offs = -100
while True:
fh.seek(offs,2)
lines = fh.readlines()
if len(lines)>1:
last = lines[-1]
break
offs *= 2
last=last.decode(encoding='utf-8')
last_id=int(last.split(',')[0])
new_id=last_id+1
#insert into db1.emp values 张国辉,30,18500841678,运维,2007-8-1
record=sql_dic.get('values')[0].split(',')
record.insert(0,str(new_id))
#['26', 'alex', '18', '13120378203', '运维', '2013-3-1\n']
record_str=','.join(record)+'\n'
fh.write(bytes(record_str,encoding='utf-8'))
fh.flush()
return [['insert successful']]
def delete(sql_dic):
db,table=sql_dic.get('from')[0].split('.')
bak_file=table+'_bak'
with open("%s/%s" %(db,table),'r',encoding='utf-8') as r_file,\
open('%s/%s' %(db,bak_file),'w',encoding='utf-8') as w_file:
del_count=0
for line in r_file:
title="id,name,age,phone,dept,enroll_date"
dic=dict(zip(title.split(','),line.split(',')))
filter_res=logic_action(dic,sql_dic.get('where'))
if not filter_res:
w_file.write(line)
else:
del_count+=1
w_file.flush()
os.remove("%s/%s" % (db, table))
os.rename("%s/%s" %(db,bak_file),"%s/%s" %(db,table))
return [[del_count],['delete successful']]
def update(sql_dic):
#update db1.emp set id='sb' where name like alex
db,table=sql_dic.get('update')[0].split('.')
set=sql_dic.get('set')[0].split(',')
set_l=[]
for i in set:
set_l.append(i.split('='))
bak_file=table+'_bak'
with open("%s/%s" %(db,table),'r',encoding='utf-8') as r_file,\
open('%s/%s' %(db,bak_file),'w',encoding='utf-8') as w_file:
update_count=0
for line in r_file:
title="id,name,age,phone,dept,enroll_date"
dic=dict(zip(title.split(','),line.split(',')))
filter_res=logic_action(dic,sql_dic.get('where'))
if filter_res:
for i in set_l:
k=i[0]
v=i[-1].strip("'")
print('k v %s %s' %(k,v))
dic[k]=v
print('change dic is %s ' %dic)
line=[]
for i in title.split(','):
line.append(dic[i])
update_count+=1
line=','.join(line)
w_file.write(line)
w_file.flush()
os.remove("%s/%s" % (db, table))
os.rename("%s/%s" %(db,bak_file),"%s/%s" %(db,table))
return [[update_count],['update successful']]
def select(sql_dic):
db,table=sql_dic.get('from')[0].split('.')
fh=open("%s/%s" %(db,table),'r',encoding='utf-8')
filter_res=where_action(fh,sql_dic.get('where'))
# print('filter_res is ====>',filter_res)
fh.close()
limit_res=limit_action(filter_res,sql_dic.get('limit'))
# print('limit_res is ====>',limit_res)
search_res=search_action(limit_res,sql_dic.get('select'))
# print('select_res is ====>',search_res)
return search_res
def where_action(fh,where_l):
res=[]
logic_l=['and','or','not']
title="id,name,age,phone,dept,enroll_date"
if len(where_l) !=0:
for line in fh:
dic=dict(zip(title.split(','),line.split(',')))
logic_res=logic_action(dic,where_l)
if logic_res:
res.append(line.split(','))
else:
res=fh.readlines()
return res
def logic_action(dic,where_l):
res=[]
# print('==\033[45;1m%s\033[0m==\033[48;1m%s\033[0m' %(dic,where_l))
for exp in where_l:
if type(exp) is list:
exp_k,opt,exp_v=exp
if exp[1] == '=':
opt='%s=' %exp[1]
if dic[exp_k].isdigit():
dic_v=int(dic[exp_k])
exp_v=int(exp_v)
else:
dic_v="'%s'" %dic[exp_k]
if opt != 'like':
exp=str(eval("%s%s%s" %(dic_v,opt,exp_v)))
else:
if exp_v in dic_v:
exp='True'
else:
exp='False'
res.append(exp)
res=eval(' '.join(res))
# print('==\033[45;1m%s\033[0m' %(res))
return res
def limit_action(filter_res,limit_l):
res=[]
if len(limit_l) !=0:
index=int(limit_l[0])
res=filter_res[0:index]
else:
res=filter_res
return res
def search_action(limit_res,select_l):
res=[]
fileds_l=[]
title="id,name,age,phone,dept,enroll_date"
if select_l[0] == '*':
res=limit_res
fileds_l=title.split(',')
else:
for record in limit_res:
dic=dict(zip(title.split(','),record))
# print("dic is %s " %dic)
fileds_l=select_l[0].split(',')
r_l=[]
for i in fileds_l:
r_l.append(dic[i].strip())
res.append(r_l)
return [fileds_l,res]
if __name__ == '__main__':
while True:
sql=input("sql> ").strip()
if sql == 'exit':break
if len(sql) == 0:continue
sql_dic=sql_parse(sql)
if len(sql_dic) == 0:continue #输入命令非法
res=sql_action(sql_dic)
for i in res[-1]:
print(i)


浙公网安备 33010602011771号