#默认参数的值是在一开始定义的时候就传给了函数, # 在后来的修改中不会被修改. #默认参数的值必须放到位置形参参数的最后面 #默认参数使用的场景是一个参数不经常变得场景,所以参数一般是不可变类型.字符串 元祖 数字 res=1 def foo(x,y=res): print(x,y) res=10 foo("aaa")
#结果是
aaa 1
def foo(x,y,*t): print(x,y) print(*t) #(3, 4, 5) foo(1,2,3,4,5) #结果是: 3 4 5 #t=(2,3,4) #星会将接受的多余的参数转化为元祖赋值给t
第十节形参和实参的传递
#===================第十节 #3.传打散的参数 def foo(x,y,*t): print(x,y) print(t) # foo(1,2,3,4,5) foo(1,2,*['a','b','c']) #这里的*['a','b','c'] 代表将列表打散成多个参数传递给函数. #以后只要见到星表示 处理的是位置参数 # 4.可变长参数 #在调用阶段 实参的个数不固定,所以形参的个数也不固定 #形参的解决方式*一个星表示位置实参传的超出的部分,** 表示 关键字实参传递的参数超出的部分. #t=(2,3,4) #星会将接受的多余的参数转化为元祖赋值给t def foo(x,y,*t): print(x,y) print(t) # foo(1,2,3,4,5) foo(1,2,*['a','b','c']) #('a', 'b', 'c') foo(*['a','b','c','d']) #('c', 'd') # 5.元祖也可以 def foo(x,y): print(x,y) foo(*(1,2)) #1 2 # 6. 约定俗称大家一般写*args代表位置参数 **kwargs 表示关键字参数.实际上这两个单词可以随便写,约定俗成这么写. # 关键字无固定个数穿参数 def foo(x,y,**kwargs): print(x,y) print(kwargs) foo(x=111,y=444,a=11,b=33,c=44,d=55,cc=99,dd=88) #####字典关键字的参数打散 def foo(x,y,**kwargs): print(x,y) print(kwargs) foo(**{'a':11,'b':'22','d':44,'x':334,'y':56}) #关键字传参数解压 def foo(x,y): print(x,y) foo(**{'x':11,'y':22}) #位置参数和关键字参数都不固定的传参数 def foo(*args,**kwargs): print(args) #这里收到一个元祖 print(kwargs) #这里收到的是一个字典 foo(1,2,3,4,**{'x':11,'y':22}) (1, 2, 3, 4) {'x': 11, 'y': 22} #将接收到的参数原封不动的传到最终调用的函数. def wrapper(x,y,z): print(x,y,z) def foo(*args,**kwargs): #封装成元祖和字典 wrapper(*args,**kwargs) #解压成各个参数表示将接收到的参数原封不动的传到最终调用的函数 foo(1,y=2,z=3) #7. 命名关键字参数表示定义在*之后的参数,该参数必须被传值.必须是key value的形式传值. #* 后面的 y 和 z就是命名关键字参数 def wrapper(x,*,y,z): print(x,y,z) wrapper(1,y=2,z=3)
第十一节函数对象的四个特性
============第十一节函数的几个特性. 1.函数可以被引用. def fun(x,y): print(x,y) f=fun f(1,2) #1 2 2.函数可以被当做参数传入. def fun(x,y): print(x,y) def fun2(): print("ttttt") def boo(fun): print(fun) boo(fun(1,2)) boo(fun2) #1 2 #None #<function fun2 at 0x031034B0> 3.可以当做函数的返回值 def fun(): print("rrrrrrrrrrr") return 11; def boo(): return fun(); tt=boo() print(tt) 4.可以当做容器类型的元素. def fun(): print("rrrrrrrrrrr") return 11; def boo(): return fun; l=[fun,boo] print(l) #[<function fun at 0x0144D5D0>, <function boo at 0x036F3468>] def fun(): print("rrrrrrrrrrr") return 11; def boo(): return fun; l=[fun,boo] print(l) print(l[0]()) #列表中取出函数加上括号就可以执行了. #[<function fun at 0x02A5D5D0>, <function boo at 0x02BA3468>] #rrrrrrrrrrr #11 #########普通的函数调用: def fun(): print("func") def get(): print("get") def set(): print("set") cmd=input("输入方法:") if cmd =="get": get() elif cmd == "set": set() elif cmd =="fun": fun() #函数放入字典的调用. def fun(): print("func") def get(): print("get") def set(): print("set") dic_fun={'fun':fun,'get':get,'set':set} dic_fun['fun']() dic_fun['get']() dic_fun['set']() dic_fun={'fun':fun,'get':get,'set':set} fc=input(">>>:") if fc in dic_fun: dic_fun[fc]()
十二节函数的嵌套定义
===================十二函数的嵌套定义和函数的嵌套定义. #函数的嵌套调用,比较4个数的最大值. def max_val(x,y): if x>y: return x else: return y print(max_val(5,3)) print(max_val(10,20)) print(max_val(max_val(5,3),max_val(10,20))) #main函数里面多个函数挨着调用也是典型的函数嵌套定义. def main(): print(max_val(6,7)) main() #函数的嵌套定义 #内部定义的函数只能在内部使用. def boo(): def ttt(): print("ppppp") print("ppppp") print("ppppp") print("ppppp")
第十三节名称空间和作用域.
==================第十三节名称空间和作用域. 名称空间存放的是名字和对应值绑定关系的地方. 内置名称空间: python内置函数存储的空间 print len max time(python解释器启动就有的) 全局名称空间,没有缩进的顶着文件头写的就是全局名称空间.文件级别定义的名字. x=1 #变量的定义 def fun():pass #函数的定义 import time class tt():pass 局部名称空间.函数调用时生效,函数调用结束失效. 加载顺序是:内置命名空间==>全局命名空间====>局部命名空间 访问名字的顺序是:局部===>全局===>内置空间.
全局作用域:全局名称空间的名字 函数globals() 局部作用域:局部名称空间的名字 函数locals() def boo(): def ttt(): aa=111 print("ppppp") print(locals(),"====") ttt() print(globals(),"----") boo() #输出结果 {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x03758510>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/PycharmProjects/wadsd/day3/函数.py', '__cached__': None, 'boo': <function boo at 0x0371C5D0>} ---- ppppp {'aa': 111} ==== # # #作用域的例子. x=1 def foo(): x=100 foo() print(x) #全局作用域的例子.global 关键字声明变量是全局变量,显示的声明 x=1 def foo(): global x x=100 foo() print(x) ============== global修改全局变量. x=1111 def foo(): x=2222 def nnn(): global x x=100 nnn() foo() print(x) #100 ============= nonlocal修改局部变量.上一层有就是上一层.上一层没有就上上一层.但是局部变量必须有.不会跑出函数. x=1111 def foo(): x=2222 def nnn(): nonlocal x x=100 nnn() print(x,"==") foo() print(x) #打破函数层级限制调用函数.return返回值返回内部函数.函数作为返回值. def oter(): def iner(): print("ttttt") return iner; print(oter()) print(oter()()) # <function oter.<locals>.iner at 0x02E73468> # ttttt # None ==========================返回函数传递后引用. def oter(): def iner(): print("ttttt") return iner; # print(oter()) # print(oter()()) f=oter() def bar(): f() bar() ==============函数作用域是在定义的阶段就固定了. x=1 def oter(): x=2 def iner(): print(x) return iner; # print(oter()) # print(oter()()) f=oter() def bar(): x=3 f() bar() #这个值是2,找不到定义的阶段上级. x=1 def oter(): def iner(): print(x) return iner; # print(oter()) # print(oter()()) f=oter() def bar(): x=3 f() bar() #去掉2是1 #去掉1会找不到变量报错. def oter(): def iner(): print(x) return iner; # print(oter()) # print(oter()()) f=oter() def bar(): x=3 f() bar() File "D:/PycharmProjects/wadsd/day3/函数.py", line 4, in iner print(x) NameError: name 'x' is not defined ==============全局名称空间的覆盖. x=1 def oter(): def iner(): print(x) return iner; # print(oter()) # print(oter()()) x=111111111111 f=oter() def bar(): x=3 f() bar() =======================关键在调用阶段,还是1111 x=1 def oter(): def iner(): print(x) return iner; f=oter() def bar(): x=3 f() x=1111111 bar() #1111111
14节闭包函数,一种新的给函数传参数的方法.
===================================14节闭包函数,一种新的给函数传参数的方法. 1定义在函数内部的函数, 2该函数的函数体包含对外部作用域 (而不是全局作用域的的调用) 3.通常return 作为外部函数的使用 def ot(): x=1 def it(): print(x) #内部作用域引用外部作用域的代码叫做闭包函数 z="ttttttttt" def ot(): x="ooooooooo" y=2 def inner(): print(x) #内部作用域引用外部作用域的代码叫做闭包函数 print(y) #内部作用域引用外部作用域的代码叫做闭包函数 return inner f=ot() print(f.__closure__[0].cell_contents) print(f.__closure__[1].cell_contents) ooooooooo 2 ============= import requests def get_url(url): rs=requests.get(url) # print(rs.text.encode(encoding='utf-8')) if rs.status_code==200: print(rs.text) get_url("http://www.baidu.com") ========================= import requests def get_url2(): url="http://www.baidu.com" def gg2(): rs = requests.get(url) # print(rs.text.encode(encoding='utf-8')) if rs.status_code == 200: print("----------") print(rs.text) return gg2 get_url2()() ====================== import requests def get_url2(url): #url="http://www.baidu.com" def gg2(): rs = requests.get(url) if rs.status_code == 200: print("----------") print(rs.text) return gg2 baidu=get_url2("http://www.baidu.com") baidu() baidu() baidu()
第十五节:简单装饰器
============15.简单装饰器. #1.开放封闭原则,对扩展是开放的,对修改是封闭的. #2.装饰器是装饰它人的,指的是任意可调用对象,现在的场景是函数 # 原则: 不修改装饰对象的源代码 2.不修改装饰对象的调用方式. #装饰器的目的: 在遵循1,2的前提下为被装饰对象添加上新功能. import time def aa(): print(6745875484895*87548758) time.sleep(2) def bb(fun): start=time.time() fun() end=time.time() print("cost time is %s" %(end-start)) bb(aa) ================简单装饰器import time def aa(): print(6745875484895*87548758) time.sleep(2) def bb(fun): def tm(): start=time.time() fun() end=time.time() print("cost time is %s" %(end-start)) return tm; # bb(aa)() aa=bb(aa)#aa==tm aa()
16装饰器修订.
==================16装饰器修订. 装饰器语法: @装饰器 #@装饰器函数的名字 到被装饰器函数的上面 import time #装饰器语法 @装饰器名字到被装饰器名字上面,装饰器写在上方,不然被装饰器先写找不到这个装饰器的名字 def bb(fun): def tm(): start=time.time() fun() end=time.time() print("cost time is %s" %(end-start)) return tm; @bb #aa=bb(aa) python遇到@符号会把下面的函数当做参数传递给上面的函数 bb(aa),并且把结果重新命名为aa,aa=bb(aa) def aa(): print(6745875484895*87548758) time.sleep(2) aa() ================================解决返回值的问题 import time #装饰器语法 @装饰器名字到被装饰器名字上面,装饰器写在上方,不然被装饰器先写找不到这个装饰器的名字 def bb(fun): def tm(): start=time.time() ff=fun() end=time.time() print("cost time is %s" %(end-start)) return ff #将函数的返回值传给装饰器 return tm; @bb #aa=bb(aa) python遇到@符号会把下面的函数当做参数传递给上面的函数 bb(aa),并且把结果重新命名为aa,aa=bb(aa) def aa(): print(6745875484895*87548758) time.sleep(2) return "方法" #函数的返回值 tt=aa() #装饰器过后获取的函数的返回值 print(tt) #获取返回值 ,应对返回值的问题 ========================================================解决参数的问题 import time #装饰器语法 @装饰器名字到被装饰器名字上面,装饰器写在上方,不然被装饰器先写找不到这个装饰器的名字 def bb(fun): def tm(ppp): start=time.time() ff=fun(ppp) end=time.time() print("cost time is %s" %(end-start)) return ff #将函数的返回值传给装饰器 return tm; @bb #aa=bb(aa) python遇到@符号会把下面的函数当做参数传递给上面的函数 bb(aa),并且把结果重新命名为aa,aa=bb(aa) def aa(ppp): print(ppp) time.sleep(2) return "方法的返回值" #函数的返回值 tt=aa('ppppppppp') #装饰器过后获取的函数的返回值 print(tt) #获取返回值 ,应对返回值的问题 =========完整版 import time #装饰器语法 @装饰器名字到被装饰器名字上面,装饰器写在上方,不然被装饰器先写找不到这个装饰器的名字 def bb(fun): def tm(*args,**kwargs): start=time.time() ff=fun(*args,**kwargs) end=time.time() print("cost time is %s" %(end-start)) return ff #将函数的返回值传给装饰器 return tm; @bb #aa=bb(aa) python遇到@符号会把下面的函数当做参数传递给上面的函数 bb(aa),并且把结果重新命名为aa,aa=bb(aa) def aa(ppp): print(ppp) time.sleep(2) return "方法的返回值" #函数的返回值 tt=aa('ppppppppp') #装饰器过后获取的函数的返回值 print(tt) #获取返回值 ,应对返回值的问题 ====十七有参装饰器============================================== ====================无参装饰器 # 创建密码文件 # f=open("mima.txt",'w',encoding='utf-8') # # f.write("egon:123") def get_db_info(): f=open('mima.txt','rt',encoding='utf-8') t=f.readline() user_info=t.split(':') f.close() return user_info def auth(fun): #这里是被装饰对象的方法函数 def inner(*args,**kwargs): #这里代表被装饰对象的参数. nm=input("输入账号>>") pwd=input("输入密码>>") user_info=get_db_info() print(user_info) if nm==user_info[0] and pwd==user_info[1]: res=fun(*args,**kwargs) return res else: print("登陆失败") return None return inner; @auth def gouwu(sp): print("购物 %s" %(sp)) return sp gouwu("苹果") ============装饰器最多包三层 第一层要传的参数 第二层 装饰的方法 第三层 包 装饰的参数 -----------有参数的装饰器 # # f=open("mima.txt",'w',encoding='utf-8') # # f.write("egon:123") def get_db_info(): f=open('mima.txt','rt',encoding='utf-8') t=f.readline() user_info=t.split(':') f.close() return user_info def auth2(engine): #engine="file" def auth(fun): def inner(*args,**kwargs): nm=input("输入账号>>") pwd=input("输入密码>>") user_info=get_db_info() print(user_info) if engine=='file': print("file") elif engine=='sjk': print('数据库') if nm==user_info[0] and pwd==user_info[1]: # res=fun(*args,**kwargs) return fun(*args,**kwargs) else: print("登陆失败") return None return inner; return auth @auth2(engine='file') def gouwu(sp): print("购物 %s" %(sp)) return sp gouwu("苹果") ------------------有参装饰器添加多个装饰器和多个装饰器有执行顺序的问题 # # f=open("mima.txt",'w',encoding='utf-8') # # f.write("egon:123") import time def get_db_info(): f=open('mima.txt','rt',encoding='utf-8') t=f.readline() user_info=t.split(':') f.close() return user_info def auth2(engine): #engine="file" def auth(fun): def inner(*args,**kwargs): nm=input("输入账号>>") pwd=input("输入密码>>") user_info=get_db_info() print(user_info) if engine=='file': print("file") elif engine=='sjk': print('数据库') if nm==user_info[0] and pwd==user_info[1]: # res=fun(*args,**kwargs) return fun(*args,**kwargs) else: print("登陆失败") return None return inner; return auth def bb(fun): def tm(*args,**kwargs): start=time.time() ff=fun(*args,**kwargs) end=time.time() print("cost time is %s" %(end-start)) return ff #将函数的返回值传给装饰器 return tm; #如果这样写意思是装饰auth2 和gouwu两个一起执行的时间的装饰器,不是单对gouwu的,------装饰器有顺序的问题如果想统计购物的时间,bb和auth2调换位置 @bb @auth2(engine='file') def gouwu(sp): print("购物 %s" %(sp)) return sp gouwu("苹果") # 输入账号>>egon # 输入密码>>123 # ['egon', '123'] # file # 购物 苹果 # cost time is 6.617653131484985 ====wrapper----------将装饰器的装饰后函数函数的注释直接调用为函数原来的注释 from functools import wraps import time def bb(fun): @wraps(fun) def tm(*args,**kwargs): start=time.time() ff=fun(*args,**kwargs) end=time.time() print("cost time is %s" %(end-start)) return tm; #如果这样写意思是装饰auth2 和gouwu两个一起执行的时间的装饰器,不是单对gouwu的 @bb def gouwu(sp): '''gouwu zhushi''' print("购物 %s" %(sp)) return sp print(help(gouwu)) ------------不加wrapper Help on function tm in module __main__: tm(*args, **kwargs) # @wraps(fun) None 加了 Help on function gouwu in module __main__: gouwu(sp) gouwu zhushi None