闭包函数闭包:定义在内网函数,包含对外部作用域而非全局作用域范围:一个函数套用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 timedef 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) 注:把正下方的函数值给timerdef 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@Gavindef guolm(): print("hello man") return guolmguolm() #相当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")的传参 就是egonindex() #wrapperhome("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)) #返回Trueprint(isinstance("hello",Iterable)) #返回Trueprint(isinstance((1,2,),Iterable)) #返回Trueprint(isinstance({ "a":"1","b":"2"},Iterable)) #返回Trueprint(isinstance({1,2,3},Iterable)) #返回Trueprint(isinstance(f,Iterable)) #返回True#判断是否为迭代器对象print(isinstance([1,2],Iterator)) #返回Falseprint(isinstance("hello",Iterator)) #返回Falseprint(isinstance((1,2,),Iterator)) #返回Falseprint(isinstance({ "a":"1","b":"2"},Iterator)) #返回Falseprint(isinstance({1,2,3},Iterator)) #返回Falseprint(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个会报错######迭代器的内存地址 124或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 生成器yieldyield的功能: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)#显示start012end显示文件,执行内容#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) ##内置函数 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 = [ 1,2,4,6,7,8,9,11,14,16,18,19,20,22,25,29] data = 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类型 获取类 #
- 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) #
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"*nstart = time.time()b=datawhile 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"*nstart = 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秒