Colin_Gu

导航

 
函数为了拓展,对于那些传入的实参数量不固定,万能参数,动态参数,通常使用*args,**kwargs表示。
1 def sum1(*args):
2     print(args)
3 sum1(1,2,3,4)  # (1, 2, 3, 4)
在函数的定义时,*args表示位置参数,作为聚合用。
*args将所有的实参的位置参数聚合到一个元组,并将这个元组赋值给args
1 def sum1(*args, **kwargs):
2     print(args)         # (1, 2, 3, 4, 5)
3     print(kwargs)
4 sum1(1,2,3,4,5, name = 'colin', age = '27')  # {'name': 'colin', 'age': '27'}
该方式下,还有拆分功能,如下列例题:将l1与l2拆分一一打印出来:
一般方法如下:

 1 def func1(*args):
 2     l = []
 3     for i in args:
 4         if type(i) is list:
 5             for j in i:
 6                 l.append(j)
 7         else:
 8             l.append(i)
 9     return l
10 l1 = [1,2,3]
11 l2 = [111,222,'alex']
12 print(func1(l1,l2))
稍微简单的方法如下:
1 def func1(*args):
2     return args[0] + args[1]
3 l1 = [1,2,3]
4 l2 = [111,222,'alex']
5 print(func1(l1,l2))
用本文介绍的方法如下:

1 def func1(*args):
2     print(args)
3 l1 = [1,2,3]
4 l2 = [111,222,'alex']
5 func1(*l1,*l2)    # (1, 2, 3, 111, 222, 'alex')

此外,对于加了两个星号 ** 的参数会以字典的形式导入。

1 def func1(*args, **kwargs):
2     print(kwargs)
3 func1(**{'name':'colin'},**{'age' : 27})  # {'name': 'colin', 'age': 27}
接下来讨论形参的顺序,比较位置参数,默认参数,*args,**kwargs的先后
位置参数,默认参数

1 def func(a, b, sex = ''):
2     print(a)  # 100
3     print(sex) #
4 func(100,200)
5 def func(a, sex = '',b):
6     print(a)
7     print(sex)
8 func(100,200)      # 报错

位置参数在前,默认参数在后,否则报错,是因为200的值赋值给默认参数sex,而b没有参数传入,所以报错
位置参数,*args,默认参数

1 def func(a,b,sex = '',*args):
2     print(a,b)  # 100 200
3     print(sex)  # 1
4     print(args) # (2, 3, 4, 5)
5 func(100,200,1,2,3,4,5)

1 def func(a,b,*args,sex = ''):
2     print(a,b)  # 100 200
3     print(sex)   #
4     print(args) # (1, 2, 3, 4, 5)
5 func(100,200,1,2,3,4,5)
从上面可以分析,若默认参数在前的化,实参1会将默认参数sex覆盖,后面的参数都给*args,
性别赋值除了问题,而默认参数放在最后则消除了这个影响,因此顺序为:位置参数,*args,默认参数

位置参数,*args,**kwargs,默认参数

1 def func(a,b,*args,**kwargs,sex =''):
2     print(a,b)
3     print(sex)
4     print(args)
5 func(100,200,1,2,3,4,5,sex ='')
1 def func(a,b,*args,sex ='',**kwargs):
2     print(a,b) # 100,200
3     print(sex)  #
4     print(args)  # (1, 2, 3, 4, 5)
5     print(kwargs) # {}
6 func(100,200,1,2,3,4,5,sex ='')
从上面分析可知,当默认参数放在最后时,会报错,这是因为不固定参数**kwargs将sex参数包括进去,
导致默认参数没有参数与它对应,导致报错。
综上:参数顺序为:位置参数,*args,默认参数,**kwargs

命名空间
在python中,名称空间可以分为三种:
1 全局名称空间
2 局部名称空间(临时):在函数的运行中开辟的临时的空间叫局部命名空间
3 内置名称空间

作用域分类
全局作用域 全局名称空间
内置名称空间
局部作用域 局部名称空间(临时)
其取值顺序为:
局部名称空间 > 全局名称空间 > 内置名称空间 单向从小到大范围

1 len = 6
2 def func1():
3     len = 3
4 func1()
5 print(len) # 6
1 count = 1
2 def func1():
3     count = count + 1  # local variable 'count' referenced before assignment
4     print(count)
5 func1()
如果你在局部名称空间,对一个变量进行修改,那么解释器会认为你的这个变量在局部中已经定义了,
但是对于上面的例题,局部中没有定义,所以他会报错。
解决方法1
1 count = 1
2 def func1():
3     count = 3
4     count = count + 1  # 4
5     print(count)
6 func1()
解决方法2: 在局部名称空间可以对全局变量进行修改
1 count = 1
2 def func1():
3     global count
4     count = count + 1  # 2
5     print(count)
6 func1()
nonlocal
子函数对父函数的变量进行修改
此变量不能是全局变量
1 def func1():
2     count = 666
3     def func2():
4         nonlocal count
5         count += 1
6         print(count)  # 667
7     func2()
8 func1()
posted on 2018-08-16 20:24  Colin_Gu  阅读(1698)  评论(0编辑  收藏  举报