第二章

本章内容

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("33[35mUser has passed authentication33[0m")
11                     res = func(*args,**kwargs)
12                     return res
13                 else:
14                     exit("33[36merror password33[0m")
15             elif auth_type == "ldap":
16                 print("33[32m----ldap----33[0m")
17         return wrapper
18     return outer_wrapper
19 
20 @auth(auth_type="local")
21 def index():
22     print("33[33mwelcom to index page33[0m")
23 
24 @auth(auth_type="ldap")
25 def home():
26     print("33[32mwelcom to home page33[0m")
27     return "from home"
28 
29 @auth
30 def bbs():
31     print("33[31mwelcom to bbs page33[0m")
32 
33 home()
34 index()
35 bbs()
Vi ew Code

    生成器

列表生成器

[ 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()
View Code

locking  

信用卡锁定用户文件
1 zhuangsan
2 lisi
View Code

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}}
View Code

sp_user 

购物商城用户密码文件
1 admin 789
View Code

docs

1 kong
View Code

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("33[36m用户%s已锁定,无法登陆!33[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
View Code

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           }
View Code

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("33[32m请输入用户名:>>33[0m:")
 27                 passwd = input("33[35m请输入密码:>>33[0m")
 28                 file_dir.sd(username)
 29                 if username in data and passwd == data[username]['Password']:
 30                     print("33[32m#############################33[0m")
 31                     print("33[31m欢迎{0}登录33[0m".format(username))
 32                     print("33[32m#############################33[0m")
 33                     login = start_time+'用户%s登录成功!
' % username
 34                     file_dir.login_log(login)
 35                     func()
 36                 count += 1
 37                 if count == 3:
 38                     log_sd = start_time + '用户%s已锁定
' % username
 39                     file_dir.locking(log_sd)
 40                     print("33[36m密码错误次数过多,用户已经锁定!请联系管理员.33[0m")
 41                 else:
 42                      print("33[31m用户名或密码错误33[0m")
 43                      error = start_time + '用户%s登录失败!
' % 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("33[32m请输入用户名:>>33[0m:")
 57         passwd = input("33[35m请输入密码:>>33[0m")
 58         file_dir.sd(usernam)
 59         if usernam in data and passwd == data[usernam]['Password']:
 60             print("33[32m#############################33[0m")
 61             print("33[31m欢迎{0}登录33[0m".format(usernam))
 62             print("33[32m#############################33[0m")
 63             login = start_time+'用户%s登录成功!
' % usernam
 64             file_dir.login_log(login)
 65             return
 66         count += 1
 67         if count == 3:
 68             log_sd = start_time + '用户%s已锁定
' % usernam
 69             file_dir.locking(log_sd)
 70             print("33[36m密码错误次数过多,用户已经锁定!请联系管理员.33[0m")
 71         else:
 72              print("33[31m用户名或密码错误33[0m")
 73              error = start_time + '用户%s登录失败!
' % 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 +"消费成功
"
 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
" % (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('
').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('
'))
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
" % 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 +"成功取款
"
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圆
" % (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
" %(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("33[34m权限不足!33[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
View Code

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消费成功
View Code

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登录失败!
View Code

shoping_log

购物历史文件
1 2017-04-25 20:52:20 han成功购买['Lumia', 3800]
2 2017-04-25 20:52:40 han成功购买['Charge', 45]
View Code

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登录成功!
View Code

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.结账直接在信用内扣除余额
View Code

requirements.txt

1 kong
View Code

 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('	',i.tag,i.attrib,i.text)  #打印值和属性
        print('	', 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("	",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='	')             #换行

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')                                                        #定义打印内容

看一下这几个日志级别分别代表什么意思

LevelWhen 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')

常用正则表达式符号

.            默认匹配除
之外的任意一个字符,若指定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") 是匹配不到的
          匹配字符结尾,同$
d          匹配字符0-9
D          匹配非数字
w          匹配[0-9a-z]
W          匹配非[0-9a-z]
s           匹配空白字符、	、
、
 , re.search("s+","ab	c1
3").group() 结果 '	'
(?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.runcomoob')
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*oow*')
print(regex.findall(test))

origin = 'hasaabc dfoujqwi halaabc m098u29841'
r = re.match('hw+',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])
View Code
 

 员工信息表

#_*_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 33[33;1m%s33[0m' %sql_dic)
    if sql_dic.get('where'):
        sql_dic['where']=where_parse(sql_dic.get('where'))

    # print('after 33[33;1m%s33[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 33[34;1m%s33[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
']
        record_str=','.join(record)+'
'
        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('==33[45;1m%s33[0m==33[48;1m%s33[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('==33[45;1m%s33[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)

  

原文地址:https://www.cnblogs.com/hanwei999/p/6678279.html