函数进阶

函数为了拓展,对于传入的实参数量不固定,万能参数,动态参数,*args, **kwargs

 1 def sum1(*args,**kwargs):  # 在函数的定义时,在 *位置参数,聚合。
 2                    # *args 将所有的实参的位置参数聚合到一个元组,并将这个元组赋值给args
 3     print(args)
 4     print(kwargs)
 5 sum1(1,2,3,4,name='alex',age=1000)
 6 def sum1(*args,**kwargs):
 7     count = 0
 8     for i in args:
 9         count = count + i
10     return count
11 print(sum1(10,10,20,30,100))
* 的魔性用法
在函数的定义时,在 *位置参数,**位置参数聚合。
在函数的调用(执行)时,在 *位置参数,**位置参数打散。
 1 l1 = [1,2,3]
 2 l2 = [111,22,33,'alex']
 3 #
 4 def func1(*args):
 5     print(args)
 6     return args[0] + args[1]
 7 print(func1(l1,l2))
 8 
 9 def func1(*args,**kwargs):
10     # print(args)
11     print(kwargs)
12 func1(*l1,*l2)
13 func1(*(1,2,3),*('alex','sb'))
14 func1(*'alex',*'sb')
15 func1(1,2,3,'alex','sb')
16 
17 func1(**{'name':'alex'},**{'age':1000})  # func1(name='alex',age=1000})
形参的顺序
位置参数,默认参数,*args,**kwargs
推到:
  1.位置参数,默认参数
1 def func(a,b,sex=''):
2     # print(a)
3     print(sex)
4 func(100,200,)

  2.位置参数,*args, 默认参数
1 def func(a,b,*args,sex='',):
2     # print(a)
3     print(a,b)
4     print(sex)
5     print(args)
6 func(100,200,1,2,34,5,6)
结论:位置参数,*args, 默认参数 **kwargs
1 def func(a,b,*args,sex='',**kwargs,):
2     print(a,b)
3     print(sex)
4     print(args)
5     print(kwargs)
6 func(100,200,1,2,34,5,6,sex='nv',name='alex',age=1000)

我们首先回忆一下Python代码运行的时候遇到函数是怎么做的,从Python解释器开始执行之后,就在内存中开辟里一个空间,每当遇到一个变量的时候,就把变量名和值之间对应的关系记录下来,但是当遇到函数定义的时候,解释器只是象征性的将函数名读如内存,表示知道这个函数存在了,至于函数内部的变量和逻辑,解释器根本不关心。

  等执行到函数调用的时候,Python解释器会再开辟一块内存来储存这个函数里面的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量回储存在新开辟出来的内存中,函数中的变量只能在函数内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。

我们给这个‘存放名字与值的关系’的空间起了一个名字-------命名空间。

代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间;

在函数的运行中开辟的临时的空间叫做局部命名空间。
'''
# python中,名称空间分三种:
# 全局名称空间
# 局部名称空间(临时)
# 内置名称空间

作用域:
全局作用域 全局名称空间 内置名称空间
局部作用域 局部名称空间(临时)

取值顺序: 就近原则
局部名称空间 ----> 全局名称空间 ----->内置名称空间 单向从小到大范围
 1  len = 6
 2  def func1():
 3      len = 3
 4  func1()
 5  print(len)
 6  def len(l):
 7      return l
 8  
 9  print(len([1,2,3]))
10 
11  print(''333)
12  input()
13 a = 1

加载顺序

内置名称空间 ----> 全局名称空间(当程序执行时) --- > 局部名称空间(当函数调用的时候)
1 def func1():
2     print(222)
3     def func2():
4         print(333)
5     print(111)
6     func2()
7     print(666)
8 func1()
9 #222 111 333 666
global nonlocal
局部名称空间 对全局名称空间的变量可以引用,但是不能改变。
 1 count = 1
 2 def func1():
 3     count = 2
 4     print(count)
 5 func1()
 6 count = 1
 7 def func1():
 8     # count = 3
 9     count = count + 1  # local variable 'count' referenced before assignment
10     print(count)
11 func1()

如果你在局部名称空间 对一个变量进行修改,那么解释器会认为你的这个变量在局部中已经定义了,

但是对于上面的例题,局部中没有定义,所以他会报错,
global
1,在局部名称空间声明一个全局变量。
1 def func2():
2     global name
3     name = 'alex'
4 func2()
5 print(name)
 2,在局部名称空间可以对全局变量进行修改。
 1 count = 1
 2 def func1():
 3     global count
 4     count = count + 1
 5     print(count)
 6 func1()
 7 print(count)
 8 
 9 nonlocal
10 def func1():
11     count = 666
12     def func2():
13         print(count)
14     func2()
15 func1()
nonlocal
子函数对父函数的变量进行修改。
此变量不能是全局变量。

在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,
并且引用的哪层,从那层及以下此变量全部发生改变。
 1 def func1():
 2     count = 666
 3     def inner():
 4         print(count)
 5         def func2():
 6             nonlocal count
 7             count += 1
 8             print('func2',count)
 9         func2()
10         print('inner',count)
11     inner()
12     print('func1',count)
13 func1()
14 #  666  func2 667  inner 667  func1 667

 

1.函数的函数名是函数的内存地址
1 def fun():
2     return '执行返回内容!'
3 print(fun)
4 print(fun())

2.函数的函数名可以作为函数参数被调用
1 def fun():
2     return '函数的返回结果'
3 fun(fun)
4 
5 def fun1():
6     print('函数fun1的返回')
7 def fun2(x):
8     x()
9 fun2(fun)   #fun作为函数fun2的参数被调用
3.函数名可以作为变量
 1 a = 1       #变量赋值的传递
 2 b = a
 3 c = b
 4 print(c)
 5 
 6 def fun():
 7     print(686868)
 8 f1= fun     #函数名作为变量赋值给另外的变量
 9 f2 =f1
10 f2()        #变量加上()可以实现fun()的函数的功能

4.函数名可以当做函数的的返回值
1 def fun():
2     def inner():
3         return 'inner的返回结果'
4     return inner
5 f2 = fun()  #返回值inner
6 print(f2()) #f2()相当于inner()
5.函数名可以作为容器类的元素
 1 def fun1():
 2     print('fun1')
 3 def fun2():
 4     print("fun2")
 5 def fun3():
 6     print('fun3')
 7 def fun4():
 8     print('fun4')
 9 li =[fun1,fun2,fun3,fun4]
10 for i in li:
11     i()
nonlocal,locals(),globals,globals()四者的区别
nonlocal申明变量可以从父级的变量进行调用
 1 def fun():
 2     a=10
 3     def inner():
 4         nonlocal a
 5         a =20
 6         print(a)
 7     inner()
 8     print(a)
 9     def two_inter():
10         a = 30
11     print(a)
12 print(fun())
globals() # 返回全局变量的一个字典。
locals() 返回 当前位置 的局部变量的字典。
 1 def func1():
 2     a = 2
 3     b = 3
 4     # print(globals())
 5     # print(locals())
 6     def inner():
 7         c = 5
 8         d = 6
 9         print(globals())
10         print(locals())
11     inner()
12 # print(globals())
13 # print(locals())
14 func1()

 

 
posted @ 2018-08-21 22:35  麒麟610  阅读(215)  评论(0编辑  收藏  举报