首页 > 代码库 > 函数+装饰器+迭代器+生成器
函数+装饰器+迭代器+生成器
闭包函数 闭包:定义在内网函数,包含对外部作用域而非全局作用域 范围:一个函数套用1或n个函数 from urllib.request import urlopen #urlopen模块 作用:爬网页 #闭包函数,内部get函数调用外部page函数 def page(url): #调用url def get(): #下载 return urlopen(url).read() #爬网页 return get #返回url值 baidu=page("http://www.baidu.com") #函数page的值,手动写的url(url可变) #print(baidu.__closure__[0].cell_contents) #看oldboy函数包裹的元素 #print(baidu.__closure__) #看oldboy函数有几个值 print(baidu()) #显示百度网页 #如下效果相同,不是闭包函数,不灵活,(不能写baidu=page("http://www.baidu.com")的形式,) def get(url): #下载 return urlopen(url).read() print(get("http://www.baidu.com")) #定义url #显示返回网页 装饰器 装饰器:装饰代码 必须遵守2个原则 最好不要修改源代码 最好不要修改调用方式 调用方式 functools模块(保存源代码的注释,更新到装饰后的程序) import time def timer(func): #func相等于index def wrapper(*args,**kwargs): #wrapper等于indiex 所有要赋值 start_time=time.time() #计算第一次执行时间 res=func(*args,**kwargs) #定义func的值给res stop_time=time.time() #计算第二次执行时间 print("run time is %s" %(start_time-stop_time)) return res #定义子函数的返回值 return wrapper #返回子函数的值 @timer #index=timer(index) 注:把正下方的函数值给timer def index(): time.sleep(3) #沉睡3秒 print("welcome to index") index() #显示是装饰后的值 #3秒后显示如下 #welcome to index #run time is -3.0002331733703613 (函数增加功能,用户认证通过后执行函数,否则提示报错信息) def Gavin(guolm): aa = ["guolm", "admin_1234"] def wrapper(*args,**kwargs): select= input("peales your writer your user>>>:") if select==aa[0]: print("ok") select1 = input("peales your writer your pass>>>:") if select1 ==aa[1]: res=guolm(*args,*kwargs) return res else: print("pass error") else: print("user error") return wrapper @Gavin def guolm(): print("hello man") return guolm guolm() #相当guolm= Gavin(guolm) 获取 用户认证+第二次不需要输入认证信息 logon_user={"user":None,‘STATUS‘:False} def auth2(driver="file"): def ahth(func): def wrapper(*args,**kwargs): if driver=="file": if logon_user["user"] and logon_user["status"]: #如果user有值并且statis是True,继续执行,#注释第一遍执行时,值不存在,所以执行else,第二次循环则成立 res=func(*args,**kwargs) #定义了函数func可n个元组,列表和n个字典 return res #第三层函数的返回值 else: name=input(">>>:") password=input(">>>:") if name == "egon" and password == "123": #如果认证成立继续执行 logon_user["user"]="egon" #改变logon_user的user值, 为上个if判断做铺垫 logon_user["status"]=True #改变logon_user的status值,为上个if判断做铺垫 res=func(*args,**kwargs) return res #第三层函数的返回值 else: print("error") elif driver == "mysql": print("show mysql") return func(*args,**kwargs) elif driver=="ldap": print("=====ldap认证") else: print("无效认证") return wrapper return ahth @auth2("file") #index函数值为file,执行如下函数#相当于调用auth2下的ahth下的wrapper函数 def index(): print("welcome to index page") @auth2(driver="mysql") #home("egon")函数值为mysql,执行如下函数 def home(name): #相当于调用auth2下的ahth下的wrapper函数 print("%s welcome to home page" %name) #name是 输入home("egon")的传参 就是egon index() #wrapper home("11") #输入11也能实现 有点不懂 迭代器 为什么要有迭代器? 对于没有索引的数据类型,必须提供一种不依赖索引的迭代方式 迭代的概念: 每次执行的结果作为下一次迭代的初始值 优点 : 提供一种不依赖下标的迭代方式,且迭代器更省内存空间(因为每次读取1行) 缺点: 不能获取迭代器对象的长度,且不如序列类型取值灵活,是一次性的,只能向后取值,不能向前 for循环也属于迭代器 可迭代的对象: 能执行.__iter__()方法为True 迭代器对象:能执行.__iter__()方法为True和执行__next__()是方法为True 可迭代对象: 只有__iter方法, 执行该方法可得到迭代器对象,只有可使用__next__方法 #数字不是迭代对象 #只是文件是迭代器,其他都可迭代对象 [1,2].__iter__() #列表 "hello".__iter__() #字符串 (1,2,).__iter__() #元组 {"a":"1","b":"2"}.__iter__() #列表 {1,2,3}.__iter__() #集合 f=open("a.txt","w") #文件 f.__iter__() #判断是否为可迭代对象 print(isinstance([1,2],Iterable)) #返回True print(isinstance("hello",Iterable)) #返回True print(isinstance((1,2,),Iterable)) #返回True print(isinstance({"a":"1","b":"2"},Iterable)) #返回True print(isinstance({1,2,3},Iterable)) #返回True print(isinstance(f,Iterable)) #返回True #判断是否为迭代器对象 print(isinstance([1,2],Iterator)) #返回False print(isinstance("hello",Iterator)) #返回False print(isinstance((1,2,),Iterator)) #返回False print(isinstance({"a":"1","b":"2"},Iterator)) #返回False print(isinstance({1,2,3},Iterator)) #返回False print(isinstance(f,Iterator)) #返回True 例如: iter确定是迭代器 next取出值 i=[1,2,4].__iter__() print(i) print(i.__next__()) #列表的值有3个 执行next每次只能取一个值 print(i.__next__()) print(i.__next__()) print(i.__next__()) #因为只有3个值,执行4个会报错 ##### <list_iterator object at 0x0000003FC1E0E2E8> #迭代器的内存地址 1 2 4 或 dic={"a":1,"b":2,"c":3,} i=dic.__iter__() #确定dic可迭代 while True: try: #尝试实现如下信息 key=i.__next__() #迭代i的值给key print(dic[key]) except StopIteration: #except是抛出异常 遇到异常StopIteration,执行break break 生成器yield yield的功能: 1 使用yield把函数变成迭代器 ,(相当于为函数封装好__iter__和__next__) 2 yield能返回多次,每次返回都会讲函数暂停,下一次next会从上一次暂停的位置继续执行,而return返回一次值,函数就终止 生成器操作 def foo(): print("first") yield 1 #之前的值 print("second") yield 2 print("fifth") g=foo() print(g) #看g的内存地址 print(next(g)) print(next(g)) #print(next(g)) #因为fifth没有加生成器yield 使用迭代器执行会保存 #或如下执行 for i in g: print(i) 生成器中使用计数器 def counter(n): print("start") i = 0 while i< n : yield i i+=1 print ("end") g=counter(3) #g是函数调用 for i in g: #for循环显示生成器的值 print(i) #显示 start 0 1 2 end 显示文件,执行内容 #1,创建a.txt文件 #2执行python #3,在db文件中输入值,最后一行开始计算,包含python的行会显示,不包含的行不显示 import time #时间模块 def tail(file): with open(file,encoding="utf-8") as f: #读取file(函数1定义的file),读取为utf-8 f.seek(0,2) #文件最尾部操作 while True: line=f.readline().strip() if line: #如果line值成立,则... yield line #返回line值,并再次从新执行函数 else: time.sleep(0.2) #沉睡0.2秒 def grep(pattern,lines): #定义了2个参数 for i in lines: if pattern in i: #pattern相当于python print(i) g=grep("python",tail("a.txt")) #g= grep函数的第二个参数是tail函数和tail调用文件,a.txt可改 for i in g: #循环显示值 print(i)
1. 名称空间与作用域
1. 全局作用域:
范围: 内置名称空间,全局名称空间 有效期:全局有效,在任何地方都可用, 不删除长期有效 查找顺序: 局部名称空间 -->全局名称空间-->内置名称空间 x=1000 def func(): x=1 def f1(): pass print(globals()) #显示全局变量中定义的名称空间的名字 print(locals()) #在全局中是看全局,在局部中是看局部 print(globals() is locals() ) #True #说明此时在全局名称空间
1.1 内置名称空间
(随着python解释器的启动而产生) print(sum) #<built-in function sum> #内置函数 import builtins #查看内置参数的模块 for i in dir(builtins): #查看有哪些内置函数 print(i)
1.2. 全局名称空间
在全局变量中定义的名称空间
#文件执行会产生全局名称空间,指定是文件级别定义的名字都会放入改空间 #如下全是全局定义, 如下有小区别 import time #模块级别定义 name="guolm" #文件级别定义 def func(): #函数级别定义 print("hello man") print(func()) class foo: #类级别定义 pass
2. 局部作用域:
范围: 局部名称空间 有效期:局局有效,在局部可用, 函数调用时有效,调用结束后失效 查找顺序: 局部名称空间 -->全局名称空间-->内置名称空间 x=1000 def func(c): x=2 print(locals()) #查看局部名称空间 func(1) {‘x‘: 2, ‘c‘: 1} #这是局部名称空间
2.1. 局部名称空间
在调用函数时,会产生局部名称空间,只在函数调用时有效,函数结束时失效
def func(): x=1 #局部名称空间 def f1(): pass
递归
最大递归层次 999层
def calc(n): #整除到1 print(n) if int(n/2) >0: calc(int(n/2)) print(n) print(calc(10))
递归 2分查找 (从N个有序数据中找到想要的值,注:无序不能查找)
#data = http://www.mamicode.com/[ 1,2,4,6,7,8,9,11,14,16,18,19,20,22,25,29] data = http://www.mamicode.com/range(1,4200000000) def binary_search(find_str,data_set,count): mid = int(len(data_set)/2) if mid==0:#代表列表只剩下一个值了,没必要继续找了 if data_set[mid] == find_str: print("find it finally",find_str,count) else: print("cannot find this num in list",find_str,count) return if data_set[mid] == find_str: print("find it",find_str,mid)# find_str in left side elif data_set[mid] > find_str: print("going to search in left ",data_set[mid],data_set[0:mid]) binary_search(find_str,data_set[0:mid],count+1) else:#find_str in right side print("going to search in right ",data_set[mid], data_set[mid+1:]) binary_search(find_str, data_set[mid+1:],count+1) binary_search(13354245, data,0)
1 内置函数
-
type 判断类型
-
name =("a","b") print(type(name)) #看name类型 获取类 #<class ‘tuple‘>
-
bool(name) 0 空格,None都是False,其他都是True
-
name =("a","b") print(bool(name))
-
len(name) 显示数据类型长度
-
name =("a","b") print(len(name))
- abs() #返回值为正数
-
print(abs(-1)) #返回1 print(abs(2)) #返回2 print(abs(-0.1)) #返回0.1
- all() #判断为True或False
-
print(all([1,2,3,4,5])) #值为True print(all([1,0])) #值为False, 值包含0,None,空都为False,其他都为True print(all([])) #值为True, 注意这是特殊情况,
- 二,八,十,十六进制
-
>>>bin(10) 二进制 ‘0b1010‘ >>> 10 十进制(默认) 10 >>> oct(10) 8进制 ‘0o12‘ >>> hex(10) 16进制 ‘0xa‘ a表示10 b表示11 以此类推
- callable 可调用对象
-
#不是函数就不可被调用返回False def func(): pass print(callable(func)) #返回True
- chr和ord
-
ascii码是美国默认字符集编码 print(chr(68)) #数字转换成ascii码 #D print(ord("D")) #ascii码转换数字 #68
- dir 查看可用参数(权限) (有5种数据类型+set等)
-
b={"1":"2"} print(dir(b))
- divmod 用于分页功能
-
print(divmod(100,3)) #取整数+余数 (33, 1)
- eval 把字符串里的命令或数据类型提取使用
-
#提取命令 cmd=‘print("三哥威武")‘ eval(cmd) #三哥威武 提取数据类型 #定义列表 keys_one=[ {"backend":"www.wy.org"}, ["server","1.1.1.3","1.1.1.3",{"weight","20"},{"maxconn","3000"}], ["server","1.1.1.4","1.1.1.4",{"weight","20"},{"maxconn","4000"}], ] #把列表写入练习文件, with open("练习","w",encoding="utf-8") as f: f.write(str(keys_one)) #转成字符串形式写入 #文件写入只能是字符串形式 with open("练习","r",encoding="utf-8") as f: dic=f.read() print(type(dic)) #字符串形式,(因为写入是就是字符串形式) dic=eval(dic) #使用eval提取出字符串中的数据类型, print(type(dic)) #列表类型 print(dic[1]) #可以查询列表内容
- frozenset 定义不可变集合
-
s=frozenset({1,2}) #s=({1,2}) 这是可变集合 s.add(3) print(s) #会报错 因为s现在是不可变集合
-
format 字符串格式化
-
s="name:{},age:{},height:{}".format("guolm",23,"183") print(s) #name:guolm,age:23,height:183
- hash 获取哈希,(2个字符串相同,哈希值相同)
-
#效果:校验的内容相同 返回的值就一致 #以后会用hash模块,略过 print(hash("aaaaa")) print(hash("aaaaa")) -3564166969462102491 -3564166969462102491
- id 取内存地址
-
#身份运算符 x=1 y=x print(id(x),id(y)) #1508750464 1508750464 print(x is y) #s 是 y #True
- pow 求余数
-
print(pow(10,2,6)) #4 #取余数 相当于10的2平方 除以6 得到的余数是4
- reversed 取反转结果
-
a=["a",2,3,4] for i in reversed(a): print(i) #显示的值是反向输出 b=["a",2,3,4] print(list(reversed(b))) #[4, 3, 2, ‘a‘] #list也是迭代器 所以值可以反转
- round 保留小数
-
one=round(3.14159,4) #最后4表示保留4位小数,第4位小数四舍五入计算 print(one) #3.1416 one=round(3.14159,3) #最后4表示保留4位小数,第4位小数四舍五入计算 print(one) #3.142 one=round(3.14159) #不输入保留位数,默认保留整数 print(one) #3
- zip #两个相同长度的字符串,元组,列表组合成字典
-
#2个不同类型也可以组合 s=("hello") a=[1,2,3,4,5] z=zip(s,a) print(z) #<zip object at 0x0000004021D90608> z变成迭代器 for i in z: print(i)
- __import__() #以字符串的形式导入模块
-
import time import time m=__import__("time") m.sleep(3) #沉睡2秒 print("Gacvin Kwok is super man")
- sum 求和
-
a=sum([1,2,3,4]) #相当于1+2+3+4 print(a) 10
- bytearray 字符串改值(在原内存空间更改.不是删除后增加)
-
a="guolm 你好" print(ascii(a)) #ascii码 a=a.encode() #改成utf-8格式 b2=bytearray(a) #可直接修改字符串 b2[0]=98 #这是g(字节)改成b(字节) print(b2) #‘guolm \u4f60\u597d‘ #bytearray(b‘buolm \xe4\xbd\xa0\xe5\xa5\xbd‘)
- map 运算
-
a= map(lambda x:x*x,range(10)) #类似三元运算 实现x=x*x 显示每次结果 运算值是0-10 #a= map(lambda x:x+1,range(10)) #类似三元运算 实现x=x+1 显示每次结果 运算值是0-10 for i in a:print(i)
- reduce 运算求加,减,乘,除
-
from functools import reduce a= reduce(lambda x,y:x+y,range(10)) #计算0-9的总和 +号可改为 * / - range中的值也可改 print(a) #45
- memoryview 在原内存空间直接修改数据
如下对比 memoryview比默认方式速度快的一个等级 import time #默认方式 原内存空间垃圾回收,开辟新内存空间, for n in (200000,400000): data=b"x"*n start = time.time() b=data while b: b=b[1:] print("memoryview",n,time.time()-start) #memoryview 200000 1.3159432411193848 #表示1.3秒 #memoryview 400000 5.632980585098267 #表示5.6秒 print("========================================") #memoryview在原内存空间直接修改 for n in (200000,400000): data=b"x"*n start = time.time() b=memoryview(data) while b: b=b[1:] print("memoryview",n,time.time()-start) #memoryview 200000 0.04102897644042969 表示0.04秒 #memoryview 400000 0.08105683326721191 表示0.08秒
函数+装饰器+迭代器+生成器
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。