装饰器:
定义:本质是函数,功能是装饰其他函数,就是为其他函数添加附加功能。
原则:1、不能修改被装饰的函数的源代码。
2、不能修改被装饰的函数的调用方式,调用还是用原函数名加(),但附加功能在里面。
高阶函数+嵌套函数==》装饰器
函数即变量。嵌套函数:在一个函数的函数体内,声明一个函数,而不是调用一个函数。
#example: import time def pisiwace(func): def deco(*args,**kwargs): 'coefficient correction' # args[0]+=2 # args[1]=args[1]*2 # args[2]+=1 time_start=time.time() func(*args,**kwargs) time_end=time.time() print('Interval time: %s '%(time_end-time_start)) return deco @pisiwace#test1=pisiwace(test1) def test1(x,y=2): "calculation" y=x**2+x*y time.sleep(2) print(x,y) return x,y @pisiwace#test2=pisiwace(test2) def test2(x,y,z): "calculation" y=x**2+x*y+z time.sleep(3) print(x,y,z) return x,y test1(2) test2(1,2,3)
当有多个装饰器本身存在参数时,可用多个函数嵌套。@login('remote')#home=login('remote')(home)
#example usename,password='wulihui',123456 def login(choise): if choise=='local': def option(func): def wrapper(x): _usename=input('usename:') _password=int(input('password:')) print(x) if usename==_usename and password==_password: source=func() return source else: print('invalid username or password') return wrapper return option elif choise=='remote': print('remote login connectting') def remote_login(x): 'remote login' return x return remote_login def _index(): 'index page' print('welcome to index page') return 'from index' @login('remote')#home=login('remote')(home) def home(): 'home page' print('welcome to home page') return 'from home' @login('local')#bbs=login(‘local’)(bbs) def bbs(): 'bbs page' print('welcome to bbs page') return 'from bbs' print(_index()) print(home()) print(bbs(3))
生成器:生成器一边循环,一边计算,生成器只有在调用的时候才能生成数据,比较节省内存。
#列表生成式
a=[i*3 for i in range(1,11,2)] print(a)
#生成器
gen1=(i*3 for i in range(1,11,2) )#定义生成器gen1 print(gen1.__next__())#取生成器中当前位置的下一个生成值,无法回到前一个值,只能逐个往后取 print(gen1.__next__()) print(gen1.__next__())
#循环调用
for i in gen1: print(i) # def fib(nmb):#这是函数 # n,a,b=0,0,1 # while n<nmb: # print(b) # a,b=b,a+b # n+=1 # return 'done' # fib(10)
元组知识补充
a,b=1,2#a=1,b=2,类似(a,b)=(1,2) a,b=b,a+b#此时先计算元组tuple=(a,a+b)=(2,1+2)=(2,3),再赋值,a=tuple[0],b=tuple[1] print(a,b)
#函数式生成器
def fib(nmb): n,a,b=0,0,1 while n<nmb: yield b#此时feb(nmb)为一个生成器,返回当前值,保留函数的中断状态 #print(b) a,b=b,a+b#含义参照tuple_knowledge.py n+=1 return 'done' #print(feb(10)) gen2=fib(10) print(gen2.__next__()) print(''.center(50,'-'))#中间可以插入其他操作 print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__()) print(gen2.__next__())#next次数超过10会报错,报的为return的值 # #异常 # g=fib(10) # 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): 'consumer generator' print('consumer %s is coming'%name) while True: baozi=yield print('steamed stuffed bun %s is coming .And it is eat by %s.'%(baozi,name)) return 'coming' def productor(): 'productor generator' c1=consumer('A') c1.__next__() c2=consumer('B') c2.__next__() print('we have prepared steamed stuffed bun') baozi_list=['肉包','菜包','花卷','糖包','灌汤包'] for i in baozi_list: print('包子做好了') c1.send(i) c2.send(i) time.sleep(1) return 'done' productor() #判断是否可循环 from collections import Iterable gen1=consumer('op') print(isinstance(gen1,Iterable))
迭代器:
可迭代对象:可直接作用于for循环的对象,称为可迭代对象
判断是否为可迭代对象方法:
from collections import Iterable print(isinstance([1,2],Iterable))
可以被next()函数调用,并不断返回下一个值的对象,称为迭代器对象:Iterator
#判断是否为迭代器对象
from collections import Iterator print(isinstance((i+2 for i in range(10)),Iterator)) print(isinstance([i+2 for i in range(10)],Iterator))
#iter(o),将list、dict、set、str变成可迭代对象
print(isinstance(iter([1,2]),Iterator))
迭代器原理:
for i in [1,2,3,4]: pass #原理如下 it=iter([1,2,3,4]) while True: try: #获得下一个值 x=next(it) except StopIteration: #遇到StopIteration就退出循环 break
计算时间间隔的函数
import time def time_count(): time_start=time.time() time.sleep(1.5) time_end=time.time() print('time count is %s'%(time_end-time_start)) time_count()
匿名函数
def sayhi(n): print(n) sayhi(3) #改成匿名函数,即没有def sayhai=lambda n:print(n) sayhi(2) anonymous=lambda x:x*2 print(anonymous(4))
内置函数:
内置函数也叫内置方法。
#all(Iterable):判断里的元素是否都为真,是的话为True,否则为False.当Iterable里存在0和False时,all(Iterable)为False print(all([2,-3,'OFF'])) print(all({0,False,3})) #any:判断里的元素是否存在真值,存在的话为True,否则为False.当Iterable里只有0和False时或什么都没有时,any(Iterable)为False print(any([])) print(any({0,False})) #ascill()把一个内存对象变成可打印的字符串形式 c={'China':'Chinese','England':'English','Japen':'Japenese'} b=ascii(c) print(type(c),c) print(type(b),{b}) #bin():将十进制整数转化为二进制表示 print(bin(63)) #bool()判断真假,0和空为假,其他为真,在可迭代对象里,存在元素即为真(包括0) print(bool(1)) print(bool(0)) print(bool('0')) #bytes(object,encoding=),将object转化为字节格式,字节格式不能修改 print(bytes('wulihui',encoding='utf-8')) #bytearray(object,encoding=):转化为ascii码数组,可以进行修改 d=bytearray('wu',encoding='utf-8') print(d,d[0]) d[0]=121 print(d,d[0]) #callable(object):判断object是否可以调用,函数和类 def test(): pass print(callable(test)) print(callable([1,2])) #chr(code),将整数返回ascii码的对应形式 print(chr(97)) #反过来讲ascii码字符转化为数字ord() print(ord('a')) #compile(object,'error.log','eval/exec'):将字符串转化为可执行对象,error.log一个文件名,执行时有错误会写进去,’eval/exec‘执行器 code='for i in range(10):print(i)' com=compile(code,'','exec') exec(com)#直接exec(code)也行,效果一样 #exec(code) #complex()复数 print(complex(1-2j)) #dict()生成一个字典 print(dict(name='wu')) #dir(object)查看object的引用方法 print(dir([])) #divmod(a,b):a/b返回商和余数,a,b必须为两个数 print(divmod(5,2)) #enumerate()#取出可迭代对象的序号和元素 list_1=['wu','dai','li'] for index,value in enumerate(list_1): print(index,value) #eval()把字符串变成字典、列表、集合等对象,处理加减乘除运算,不能处理存在语句的对象 dict1="{'China':'Chinese','England':'English'}" list1='[1,2,3]' y='2*3+4/2' print(type(dict1),type(list1)) dict1=eval(dict1) list1=eval(list1) print(dict1['China'],list1[0]) print(eval(y)) #exec():将字符串转化为可执行对象,可以处理语句或函数的对象 code=''' def sayhi(): print('hi') sayhi()''' exec(code) #filter(function,Iterable),对可迭代对象生成的数据进行过滤,function为过滤函数 filter1=filter(lambda n: n>3,range(10))#把为真的值选出来 for i in filter1: print(i) #map(function,Iterable)对可迭代对象生成的数据进行处理,function为处理函数 map1=map(lambda n:n>3,range(10))#判断是否为真 for i in map1: print(i) map2=map(lambda i:i*2,range(10))#相当于map2=[i*2 for i in range(10)] #reduce(): import functools reduce1=functools.reduce(lambda x,y:x+y*2,range(4))#range()里的值赋给y print(reduce1) #flout()转成浮点类型 #format():格式转换 print(format(2918))#转成str print(format(0x500, 'X'))#转成16进制 print(format(3.14, '010'))#显示10位数,在整数左边补0,等号可以省略010,超过10位则不变,小数点算一位 print(format(3.14159, '05.3'))#四舍五入保留3位有效数字,并显示5位,小数点算一位 print(format(3.14159, 'E'))#改成科学计数法 print(format('test', '<20'))#站位20个,左对齐 print(format('test', '>20'))#站位20个,右对齐 print(format('test', '^20'))#站位20个,居中对齐 print(format(-3.14159, '+'))#显示正负号,与‘-’同 #frozenset()不可变的集合,无法添和删 #globals()#生成一个字典,返回当前程序所有全局变量的key:value格式 print(globals()) print(globals().get('list_1')) #hash(object):将object转化为一个数字,形成映射,方便查找 print(hash('wulihui')) #help查看帮助 help(format) #hex():转成16进制 print(hex(56)) #id():返回内存地址 numb23=23 print(id(numb23)) #locals():#生成一个字典,返回当前位置所有局部变量的key:value格式,一般放在函数等内部 print(locals()) #max():返回最大值 print(max([123,455,66])) print(max({1,3,5,99999,45,7})) print(max(1,3,5,9,45,7)) print(max({1:2,3:13,5:999999,9:44,45:20,7:33}))#选出最大的key #min():返回最小值 #oct():转8进制 print(oct(10)) #pow(a,b):计算a**b print(pow(3,4)) #repr(o):用字符串表示对象,相当于ascii(),把一个内存对象变成可打印的字符串形式 #reversed(o):翻转,把序列反过来,第一个变成最后一个 #round(a,num):圆整,四舍五入保留几位小数,num为保留小数位数 print(round(3.141592653,3)) #slice(start,stop):切片 list_2=[0,1,2,3,5,6,7,8,9,10] print(list_2[slice(2,8,2)])#取list_2[2:8:2] print(list_2[2:8:2])#结果同上 list_3=range(10) list_4=list_3[slice(2,8)] print(list_4) for i in list_4: print(i) #sorted(iterable, key=None, reverse=False): 以升序返回包含iterable中所有项的新列表。 dict2={1:2,-3:9,5:10,7:-9,8:8} print(sorted(dict2.items()))#对字典转化成的元组进行排序,默认以元组中第一个元素排序,升序 print(sorted(dict2.items(),key=lambda x:x[1],reverse=True))#以value进行排序,降序 #sum(iterable, start=0, /):返回'start'值的总和(默认值:0)加上可迭代的数字 print(sum(range(5),10))#0+1+2+3+4+10 #zip(o):把两个可迭代对象拼起来,元素个数不匹配,按照少的进行匹配,当最短的可迭代用尽时停止。 list_a=[1,2,3,4] list_b=['a','b','c','d'] list_c=zip(list_a,list_b) for i in list_c: print(i) #__import__(name, globals=None, locals=None, fromlist=(), level=0) :导入模块 __import__('anonymous function')#相当于import anonymous function
json&pickle序列化:
文件只能以字符串或者二进制进行储存。序列化:把内存对象转化为字符串。
#将内存对象存入文件 set_1={'China':'Chinese','UK':'English'} with open('test.txt','w',encoding='utf-8') as f: f.write(str(set_1)) #标准的序列化方法: import json with open('text2.txt','w',encoding='utf-8') as f : f.write(json.dumps(set_1)) #json.dump(set_1,f)功能同上 #json.dumps(o):将``obj``序列化为JSON格式的``str``。 #json 只能处理简单的数据,例如字典、列表等,json在所有语言中都是互通的,主要用于各个语言之间的转换 # 以下情况处理不了 # def sayhi(name): # print('hi,%s'%name) # set_2={'China':'Chinese', # 'func':sayhi} # json.dumps(set_2) ####pickle 序列化,pickle可以序列化python里的所有类型,用法和json完全相同,转化成了bytes类型,pickle只能在python里用 import pickle def sayhi(name): print('hi,%s'%name) set_2={'China':'Chinese', 'func':sayhi} with open('text3.txt','wb') as f2: #f2.write(pickle.dumps(set_2))#功能同下 pickle.dump(set_2,f2) #dump序列化json.dump(o,fp):将``obj``序列化为JSON格式化的流为``fp``(a``.write()`` - 支持类文件对象)。 #不要在一个文件里dump多次,需要存多个dump时,分开存在多个文件里
json&pickle序列化:
#反序列化 with open('test.txt','r',encoding='utf-8') as f: data=f.read() print(data) data1=eval(data) print(data1['China']) #标准json反序列化: import json with open('text2.txt','r',encoding='utf-8') as f1 : data3=json.loads(f1.read())#等同于data3=json.load(f1) print(data3['UK']) #pickle 反序列化,pickle只能在python语言里可用 import pickle def sayhi(name): print('hi,%s'%name) with open('text3.txt','rb') as f2: data4=pickle.loads(f2.read())#等同于data4=pickle.load(f2) data4['func']('wulihui')
打印文件的路径和导入环境变量:
print(__file__)#打印当前程序文件的相对路径(执行程序的路径) import os print(os.path.abspath(__file__))#打印当前程序文件的绝对路径(文件所在路径) print(os.path.dirname(os.path.abspath(__file__)))#打印当前程序文件的目录路径(上一级目录) general_content=os.path.dirname(os.path.dirname(os.path.abspath(__file__))) print(general_content) #声明环境变量 import sys sys.path.append(general_content) import day1 from day1 import homework2#导入general_content/day1/homework2文件
Project的标准目录结构:
Foo/#程序名
|--Readme#项目说明文件
|--bin |--foo#执行程序入口,程序启动入口,调用main.py
|--conf#配置文件
|foo/#主程序目录
| |--tests/#测试用例,存放单元测试代码
| | |--__init__.py
| | |--test_main.py
| |
| |--__init__.py
| |--main.py#主程序源代码存放,程序主入口
|
|--docs/文档存放
| |--conf.py
| |--abc.rst
|
|--setup.py#安装部署脚本
|--requirements.txt#依赖关系,存放软件依赖的外部包列表
Readme 应当包含以下部分:
1、软件定位,软件的基本功能
2、运行代码的方法、安装环境、启动命令等
3、简要的使用说明
4、代码目录结构说明,更详细点可以说明软件的基本原理
5、常见问题说明