3-1 函数和装饰器

一 函数的定义和调用

def 关键字 函数名(设定与变量相同):
   函数体

例子

 1 #函数定义 2 def mylen(): 3     """计算s1的长度""" 4     s1 = "hello world" 5     length = 0 6     for i in s1: 7         length = length+1 8     print(length) 9 10 #函数调用  11 mylen()

二 函数的返回值return

 1    1,遇到return,结束函数。 2     def func1(): 3         print(11) 4         print(22) 5         return 6         print(333) 7         print(444) 8     func1() 9     2,给函数的调用者(执行者)返回值。10         无 return 返回None11         return 不写 或者 None 返回None12         return 返回单个数.13         return 返回多个数,将多个数放在元组中返回。14 '''

1 没有返回值

 1 #函数定义 2 def mylen(): 3     """计算s1的长度""" 4     s1 = "hello world" 5     length = 0 6     for i in s1: 7         length = length+1 8     print(length) 9 10 #函数调用11 str_len = mylen()12 #因为没有返回值,此时的str_len为None13 print('str_len : %s'%str_len)14 15 没有return

2 返回多个值

 1 # def my_len(): 2 #     count = 0 3 #     for i in s1: 4 #         count += 1 5 #     return 666,222,count,'老男孩' 6 # print(my_len(),type(my_len())) 7  8  9 10 # def my_len():11 #     count = 012 #     for i in s1:13 #         count += 114 #     return 666,222,count15 # ret1,ret2,ret3 = my_len()  # (666, 222, 19,)16 # print(ret1)17 # print(ret2)18 # print(ret3)

3 返回一个值

 1 #函数定义 2 def mylen(): 3     """计算s1的长度""" 4     s1 = "hello world" 5     length = 0 6     for i in s1: 7         length = length+1 8     return length 9 10 #函数调用11 str_len = mylen()12 print('str_len : %s'%str_len)13 14 return返回一个值

三 函数的传参

 1 li = [1, 2, 3, 43, 'fdsa', 'alex'] 2 s1 = 'fdsgdfkjlgdfgrewioj' 3  4 # def my_len(a):  # 函数的定义()放的是形式参数,形参 5 #     count = 0 6 #     for i in a: 7 #         count += 1 8 #     return count 9 # ret = my_len(li)  # 函数的执行() 实际参数,实参10 # print(ret)11 # print(len(s1))

3.1 实参分为:

位置参数。 必须一一对应,按顺序
# def func1(x,y):
#     print(x,y)
# func1(1, 2)
#2,关键字参数。必须一一对应,不分顺序。
# def func1(x,y,z):#     print(x,y,z)# func1(y=2,x=1,z=5,)
混合参数。一一对应 且 关键字参数必须在位置参数后面。
1 # def func2(argv1,argv2,argv3):2 #     print(argv1)3 #     print(argv2)4 #     print(argv3)5 # func2(1,2,argv3=4)

3.2 形参分为

#1,位置参数。 必须一一对应,按顺序
# def func1(x,y):#     print(x,y)# func1(1,2)
默认参数。 必须在位置参数后面。
1 # def register(name,sex='男'):2 #     with open('log1',encoding='utf-8',mode='a') as f1:3 #         f1.write("{} {}\n".format(name,sex))4 # register('aa')

 

动态参数 *args,**kwargs 万能参数
# kwargs接收的只是键值对的参数,并保存在字典中
#args接收除去键值对以外的所有参数,保存成元组形式
1  ##动态参数 *args  **kwargs2 # def func2(*args,**kwargs):3 #     print(args)  ##打印成元组4 #     print(kwargs) ##打印成字典5 # func2(1,2,2,3,4,5,'alex','老男孩',a='ww',b='qq')

三种参数的混合排序

 1 # def func3(a,b,*args,sex='男'):  ##顺序是 位置参数,*args ,默认参数 2 #     print(a) 3 #     print(b) 4 #     print(sex) 5 #     print(args) 6 # func3(1,2,'老男孩','alex',sex='女') 7  8  9 # def func4(a,b,*args,sex='男',**kwargs): ##位置参数,*args,默认参数,**kwargs10 #     print(a)11 #     print(b)12 #     print(args)13 #     print(sex)14 #     print(kwargs)15 # func4(1,2,3,'alex','aa',sex='女',name='alex')

 

打散

 1 # def func1(*args,**kwargs): 2 #     print(args) 3 #     print(kwargs) 4 # l1 = [1,2,3,4] 5 # l11 = (1,2,3,4) 6 # l2 = ['alex','wusir',4] 7 # func1(*l1,*l2,*l11)    ##这个是以元组出现的 8 打印出来的结果:
  (1, 2, 3, 4, 'alex', 'wusir', 4, 1, 2, 3, 4)10 11 def func1(*args,**kwargs):12     print(args)13     print(kwargs)14 dic1 = {'name1':'alex'}15 dic2 = {'name2':'wusir'}16 func1(**dic1,**dic2)   ##出来的结果是以字典形式存在的
打印出来的结果:
{'name1': 'alex', 'name2': 'wusir'}

 

 四 函数的命名空间和作用域

命名空间一共分为三种:

  全局命名空间

  局部命名空间

  内置命名空间

*内置命名空间中存放了python解释器为我们提供的名字:input,print,str,list,tuple...它们都是我们熟悉的,拿过来就可以用的方法。

三种命名空间之间的加载与取值顺序:

加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

取值顺序:

  在局部调用:局部命名空间->全局命名空间->内置命名空间

  在全局调用:全局命名空间->内置命名空间

综上所述,在找寻变量时,从小范围,一层一层到大范围去找寻。

作用域

作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。

全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效

局部作用域:局部名称空间,只能在局部范围内生效

4.1 命名空间

 1 # name = 'wusir'  ##全局命名空间 2 # age = 12 3 # def func1(): 4 #     name1 = 'wusir'  ##局部命名空间 5 #     age1 = 34 6 #     return name1 7 # print(func1()) 8 # print(name) 9 10 11 # name1 = 'wusir'12 # def func1():13 #     print(name1)14 #     def func2():15 #         print('xxxxx',name1)16 #     func2()17 # func1()

查看命名空间

1 # name1 = 'wusir'2 # def func1():3 #     name2 = 'laonanhai'4 #     print(globals())  ##查看全局变量5 #     print(locals())  ##查看局部变量6 # func1()

4.2   

##global 关键字   声明全局空间,如果已经存在则更改
 1 #global  ##声明一个全局变量(限于字符串,数字) 2 # name = 'wusir' 3 # def func1(): 4 #     global name  ##声明一个全局变量 5 #     name = 'alex' 6 #     return 7 # func1() 8 # print(name)  ##打印的结果是alex 9 10 11 12 #对可变数据类型(list,dict,set)可以直接引用不用通过global。13 # li = [1,2,3]14 # dic = {'a':'b'}15 #16 # def change():17 #     li.append('a')18 #     dic['q'] = 'g'19 #     print(dic)20 #     print(li)21 # change()22 # print(li)23 # print(dic)
nonlocal  ##1不能修改全局变量
#2在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,
# 并且引用的哪层,从那层及以下此变量全部发生改变
 1 # def func2(): 2 #     name1 = 'alex' 3 #     print('+',name1) 4 #     def inner(): 5 #         nonlocal name1 6 #         name1 = 'wusir' 7 #         print('*',name1) 8 #         def inner1(): 9 #             pass10 #     inner()11 #     print('%',name1)12 # func2()

4.3 函数名

 1 # #1 可以互相赋值 2 # def func1(): 3 #     print(666) 4 # f1 = func1 5 # f1() 6  7 #2 函数名可以当成函数的参数 8 # def func1(): 9 #     print(777)10 # def func2(argv):11 #     argv()12 #     print(999)13 # func2(func1)14 15 #可以当成容器类数据类型的参数16 # def func1():17 # #     print(666)18 # # def func2():19 # #     print(777)20 # # def func3():21 # #     print(888)22 # # ll = [func1,func2,func3]23 # # for i in ll:24 # #     i()25 26 27 #函数名可以当成函数的返回值28 # def func1():29 #     print(666)30 # def func2(argv):31 #     print(777)32 #     return argv33 # ret = func2(func1) ##func2执行  并且把func1传给了argv而argv又返回给了ret,所以ret=func134 # ret()

4.4 闭包

闭包 内层函数对外层函数非全局变量的引用,叫做闭包
#闭包的好处:如果python 检测到闭包,
# 他有一个机制,你的局部作用域不会随着函数的结束而结束
# def wrapper():#     name1 = '老男孩'#     def inner():#         print(name1)#     inner()#     print(inner.__closure__)  ##如果返回是cell是闭包# wrapper()# name1 = '老男孩'# def wrapper():#     def inner():#         print(name1)#     inner()#     print(inner.__closure__)  ##返回none不是闭包# wrapper()name = 'alex'def wrapper(argv):def inner():print(argv)
    inner()print(inner.__closure__)  # cellwrapper(name)

 五 装饰器

 

装饰器:在不改变原函数即原函数的调用的情况下,
# 为原函数增加一些额外的功能,打印日志,执行时间,登录认证等等。

 

5.1 最简单的装饰器

 

 1 # # ##最简单的装饰器 2 import time 3  4 # def func1(): 5 # #     print('hello world') 6 # #     time.sleep(0.3) 7  8 # # def timer(f1):  #f1 = func1 9 # #     def inner():10 # #         start_time = time.time()11 # #         f1()  ##相当于执行func1()12 # #         end_time = time.time()13 # #         print('此函数的执行效率%s' %(end_time - start_time))14 # #     return inner  ##inner返回给了func115 # # func1 = timer(func1)16 # # func1()   ##执行inner()

 

5.2 @  第二种装饰器
 1 # def timer(f1): 2 #     def inner(): 3 #         start_time = time.time() 4 #         f1() 5 #         end_time = time.time() 6 #         print('此函数的执行效率是%s' % (end_time-start_time)) 7 #     return inner 8 # 9 # @timer  ##func1 = timer(func1) =inner10 # def func1():11 #     print('hello world')12 #     time.sleep(0.3)13 # func1()  ##相当于执行了inner()  ,然后返回到上面 执行inner里面的语句,14 # @timer15 # def func2():16 #     print('你好,世界')17 #     time.sleep(0.4)18 # func2()

5.3 #被装饰的函数带参数

 1 # def timer(f1):  ##f1 = func1 2 #     def inner (*args,**kwargs): 3 #         start_time = time.time() 4 #         f1(*args,**kwargs)  ##func1函数是在这步开始执行的func1(111,222) 5 #         end_time = time.time() 6 #         print('此函数的执行效率是%s' %(end_time-start_time)) 7 #     return inner 8 # @timer #func1 = timer(func1)  ##inner=func1 9 # def func1(a,b):10 #     print(a,b)11 #     print('hello world')12 #     time.sleep(0.9)13 # func1(111,222)  ##inner  把 111和222传给了上面的inner(*args)

5.4 被装饰的函数带返回值

 1 def timer(f1): 2     def inner(*args,**kwargs): 3         start_time = time.time() 4         ret = f1(*args,**kwargs)  ##func1(111,222) 5         end_time = time.time() 6         print('此函数执行效率%s' % (end_time-start_time)) 7         return ret  ##返回给了func1 8     return inner 9 @timer  #func1 = timer(func1)10 def func1(a,b):11     print(a,b)12     print('hello world')13     time.sleep(0.4)14     return 66615 ret2 = func1(111,222)  ##inner(111,222)16 print(ret2)

 

 

上一篇:Python基础——第九章 第三部分 闭包、递归、回调


下一篇:容器镜像