装饰器:
本质是函数,装饰其他函数。为其他函数添加附加功能
原则:1 不能修改被装饰的函数的源代码
2 不能修改被装饰的函数的调用方式
实现装饰器知识储备:
1,函数即变量
2 高阶函数
把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能
返回值中包含函数名(不修改函数的调用方式)
3 嵌套函数
高阶函数+嵌套函数=》装饰器
mport time
def timmer(func):
def warpper(*args,**kwargs):
start_time=time.time()
func()
stop_tiome=time.time()
print('the func run time is %s'%(stop_tiome- start_time))
return warpper
@timmer
def test1():
time.sleep(3)
print('in the test1')
test1()
def test1(func):
print(func)
func()
def foo():
print('in the hanshu')
test1(foo)
#结果:<function foo at 0x00BF3198> foo的内存地址 相当于一个,门牌号,然后加上()方法便可运行
func=foo
func() #in the hanshu
import time
def bar():
time.sleep(3)
print('in the bar')
def test1(func):
start_time=time.time()
func() #run bar
stop_time=time.time()
print('the func run time isd %s'%(stop_time-start_time))
#修改了函数的调用方式
test1(bar)
def bar():
time.sleep(3)
def test2(func):
print(func)
return func
print(test2(bar))
#结果:<function bar at 0x00BF31E0>
#<function bar at 0x00BF31E0>
#高阶函数调用,未修改函数的调用方式
t=test2(bar)
t() #run bar
bar=test2(bar)
bar() #run bar
装饰器实现: @timer =test1=timer(test1)
import time
def timer (func): #timer(test1) func=test1
def deco():
start_time=time.time()
func()#run test1()
stop_time=time.time()
print('the func run time is %s' %(stop_time-start_time))
return deco #调用高阶函数
test1=timer(test1)
test1() # --调用deco
@timmer
def test2():
print('sbd)'
test2()
同用的带有参数的装饰器:
import time
def timer (func): #timer(test1) func=test1
def deco(*args,**kwargs):
start_time=time.time()
func(*args,**kwargs)#run test1()
stop_time=time.time()
print('the func run time is %s' %(stop_time-start_time))
return deco #高阶函数
@timer
def test3(name,age):
print('info:',name,age)
test3('sjadh',13)
整合在一起:
user,passward='aaa','sss'
def auth(func):
def wrapper(*args,**kwargs):
username=input('UserName:').strip()
passward=input('Passward:').strip()
if user == username and passward==passward:
print("\033[32;1mUser has passward authentication\033[0m")
func(*args,**kwargs)
else:
exit("\033[31;1mInvalid username or passward\033[0m")
return wrapper
@auth
def index():
print('welcome to index page')
@auth
def homme():
print('welcome to the home page')
return 'from home'
@auth
def bbs():
print('welcomee to the bbs')
index()
homme()
bbs()
print(homme()) #得不到home的结果‘from home' 实际是调用wrapper wrapper没有返回值
想要返回结果‘from home’
user,passward='aaa','sss'
def auth(func):
def wrapper(*args,**kwargs):
username=input('UserName:').strip()
passward=input('Passward:').strip()
if user == username and passward==passward:
print("\033[32;1mUser has passward authentication\033[0m")
res=func(*args,**kwargs) #from home
return res
else:
exit("\033[31;1mInvalid username or passward\033[0m")
return wrapper
@auth
def index():
print('welcome to index page')
@auth
def homme():
print('welcome to the home page')
return 'from home'
@auth
def bbs():
print('welcomee to the bbs')
index()
homme()
bbs()
print(homme()) #得不到home的结果‘from home' 实际是调用wrapper wrapper没有返回值
@auth(auth_type=“local”) 装饰器带有参数
user,passward='aaa','sss'
def auth(auth_type):
print("auth func",auth_type)
def outer_wrapper(func):
def wrapper(*args,**kwargs):
print("wrapper func args:",*args,**kwargs)
if auth_type == "local":
username=input('UserName:').strip()
passward=input('Passward:').strip()
if user == username and passward==passward:
print("\033[32;1mUser has passward authentication\033[0m")
res=func(*args,**kwargs) #from home
print("------afte authentication")
return res
else:
exit("\033[31;1mInvalid username or passward\033[0m")
elif auth_type == "ldap":
print("实现。。。。")
return wrapper
return outer_wrapper
def index():
print('welcome to index page')
@auth(auth_type="local") # home = wrapper()
def home():
print('welcome to the home page')
return 'from home'
@auth(auth_type="ldap")
def bbs():
print('welcomee to the bbs')
index()
#homme()
print(home()) #得不到home的结果‘from home' 实际是调用wrapper wrapper没有返回值
bbs()
迭代器&生成器
生成器
通过列表生成式,可以直接创建一个列表,但受内存限制,列表容量有限。创建一个包含100万个元素的列表不仅占用很大的存储空间,如果仅需要访问前面几个元素,后面绝大元素占用空间被浪费掉
如果列表元素按照某种算法推算出来,我们是否可以在循环过程中不断推算出后续的元素,这种一边循环一边计算的机制称为生成器。
第一种,把一个列表生成式的【】改为(),就创建了一个generator()
L=[x * x for x in range(10)]
print(L) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
g=(x * x for x in range(10))
print(g) #<generator object <genexpr> at 0x00BF8800>
L是一个list g是一个generator
生成器 只有在调用的时候才会生成相应的数据
只记录当前位置
只有一个_next_() 方法。或 next()
斐波拉契数列 :除第一个第二个数外,任意一个数都可由前两个数相加得到
def fib(max):
n,a,b =0,0,1
while n<max:
print(b)
a,b=b,a+b
n=n+1
return 'done'
fib(10)
a,b=b,a+b在这里相当于:
t=(b,a+b) t 是一个tuple
a=t[0]
b=t[1]
yield作用:
def fib(max):
n,a,b =0,0,1
while n<max:
# print(b)
yield b #输出生成器 <generator object fib at 0x00BF89B8>
a,b=b,a+b
n=n+1
return 'done' #当不用for循环输出,用next方法则数据超出时会产生一个异常
#异常大打印消息
print(fib(10)) #输出生成器 <generator object fib at 0x00BF89B8>
f=fib(10)
print(f.__next__()) #生成器下一个值
出现异常可以用try来判断:
g = fib(6)
while True:
try:
x = next(g)
print('g:', x)
except StopIteration as e:
print('Generator return value:', e.value)
break
生成器并行
import time
def consumer(name):
print("%s 准备吃包子啦!" %name)
while True:
baozi = yield
#yield保存当前状态然后返回,返回之后再——next又到了yield ,send调用yield同时给yield传值
print("包子[%s]来了,被[%s]吃了!" %(baozi,name))
c = consumer("ChenRonghua")
c.__next__()
b1= "韭菜馅"
c.send(b1) #send调用yield同时给yield传值
c.__next__() #只调用,唤醒yield
协程式并行
import time
def consumer(name):
print("%s 准备吃包子啦!" %name)
while True:
baozi = yiel
print("包子[%s]来了,被[%s]吃了!" %(baozi,name))
def producer(name):
c = consumer('A')
c2 = consumer('B')
c.__next__()
c2.__next__()
print("老子开始准备做包子啦!")
for i in range(10):
time.sleep(1)
print("做了1个包子,分两半!")
c.send(i)
c2.send(i)
producer("vick")
迭代器:
可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list,tuple,dict,set,str等
一类是generator包括生成器和带yield的generator function
这些可以直接作用于for循环的对象成为可迭代对象:Iterable
可以使用isinstance()判断一个对象是否是Iterable对象
from collections import Iterable
isinstance([],Iterable)
isinstance({},Iterable)
isinstance('abc',Iterable)
isinstance((x for x in range(10)),Iterable) #true
isinstance(100,Iterable) # false
生成器不但可以作用于for循环,海可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值
可以被next()函数调用并不断返回下一个值的对象成为迭代器:Iterator
可以使用isstance()判断一个对象是否是Iteator对象
from collections import Iterator
isinstance([],Iterator
isinstance({},Iterator)
isinstance('abc',Iterator) #false
生成器都是Iterator对象,但list dict str 虽然是Iterable,却不是Inerator
把list,dict, str 等Iteable变成Iterator可以使用iter()函数
isinstance(iter[],Iterator
Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误,可以吧这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不多按通过next()函数实现按需计算下一个数据,所以Iterator的计算式惰性的,只有在需要返回下一个数据时它才会计算。
Iterator甚至可以表示一个无限大的数据流,例如全体自然数
for x in range (10)相当于
it =iter([1,2,…10])
while true:
try:
x =next(it)
…
3.7 里 f.next ,for line in f
2.7 里 f.xreadlines() f.xrange() 迭代器取值
json
序列化与反序列化
序列化1
#将字典的内容存储到文本
info = {
'name':'alex',
'age':22,
}
f = open("test.text","w")
f.write( str (info) )
f.close()
反序列化1:
f = open("test.text","r")
data=eval(f.read())
f.close()
print(data['age'])
序列化2
import json
info = {
'name':'vick',
'age':22,
}
f = open("test.text","w")
print(json.dumps(info))
f.write( json.dumps(info) )
f.close()
反序列化2:
import json
f = open("test.text","r")
data=json.loads(f.read())
print(data['age'])
json只能处理简单的数据,字典列表字符串等,所有语言都能同用,json的作用是所有语言之间的交互。
pickle可以序列化pyth所有的数据类型,但是在反序列化时会出现异常,因为pickle序列化后的定义的 hanhu()对象它的内存地址会当场释放掉,找不到对象
序列化3:
import json
import pickle
def hanhu(name):
print("hello,",name)
info = {
'name':'vick',
'age':22,
'func':hanhu
}
f = open("test.text","wb")
print(pickle.dumps(info)) #pickle.dumps(info))默认变为了二进制文件
f.write(pickle.dumps(info) ) #text中内容:�}q (X nameqX alexqX ageqKu.
f.close()
反序列化3:
import pickle
f = open("test.text","rb")
data=pickle.loads(f.read())
print(data['age'])
#运行结果:AttributeError: Can't get attribute 'sayhi' on <module '__main__' from 'C:/Documents and Settings/Administrator/PycharmProjects/untitled/day4/json反序列化.py'>
避免异常只能重新定义,只要定义的函数名相同,但其实它找到的内容是重新定义的那个函数:
import pickle
def hanhui(name):
print("hello2,",name)
f = open("test.text","rb")
data = pickle.loads(f.read())
print(data["func"]("vick"))
序列化4:pickle.dump(info,f) 完全相当于 f.write( pickle.dumps( info) )
import pickle
def sayhi(name):
print("hello,",name)
info = {
'name':'vick',
'age':22,
'func':hanhu
}
f = open("test.text","wb")
pickle.dump(info,f) #f.write( pickle.dumps( info) )
f.close()
反序列化4: data = pickle.load(f) 相当于 data = pickle.loads(f.read())
import pickle
def hanhu(name):
print("hello2,",name)
f = open("test.text","rb")
data = pickle.load(f) #data = pickle.loads(f.read())
print(data["func"]("Alex"))
序列化5:一般编程使用json时 dumps和load只写一次,重新写覆盖
import json
info = {
'name':'alex',
'age':22,
}
f = open("test.text","w")
f.write( json.dumps( info) )
info['age'] = 21
f.write( json.dumps( info) )
f.close()
反序列化5:
import json
f = open("test.text","r")
#data = json.loads(f.read()) #data = pickle.loads(f.read())
for line in f:
print(json.loads(line)) #load只能一次在3.0里 这里便会出现异常
file :当前程序的相对路径
import os
print(os.path.abspath(__file))):当前程序的绝对路径
print(os.dirname(os.path.abspath(__file)))):返回目录名,不要文件名BASE_DIR = os.path.dirname( os.path.dirname( os.path.abspath(file) ) ):再返回上级目录
在同一个项目下子包下调用其他包目录下的文件,执行其方法
import os
import sys
BASE_DIR = os.path.dirname( os.path.dirname( os.path.abspath(__file__) ) )
sys.path.append(BASE_DIR)
from conf import settings
from core import main
main.login()
模拟实现一个ATM+购物商城的程序
1 额度150000或自定义
2 实现购物商城,买东西加入购物车,调用信用卡接口结账
3 可以提现,手续费%5
4
5 支持多账户登录
6 支持账户间转账
7 记录每月日常消费流水
8 提供还款接口
9 ATM记录操作日志
10 提供管理接口,包括添加账户,用户额度,冻结账户
11用户认证用装饰器
https://www.cnblogs.com/lianzhilei/p/5786223.html