函数动态参数,作用域

本节主要内容

  1,函数参数--动态参数

  2,名称空间,局部名称空间,全局名称空间,作用域,加载顺序

  3,函数的嵌套

  4,global,nonlocal

一,函数参数--动态参数

  形参的动态参数:

  1,动态接受位置参数

  

def chi(*food):
    print('我要吃', food)

chi('大米', '小米')

# 结果
# 我要吃 ('大米', '小米')  多个参数传递进去,收到的内容是元组tuple

 注意:动态接受参数的时候要注意:动态参数必须在位置参数的后面

否则,动态参数放置到前面,动态参数会接受到所有的参数,位置参数不会有任何值,报错

def chi(*food, a, b):
    print('我要吃', food, a, b)

chi('大米饭', '小米饭', a = '馒头', b = '面条')  # 必须要用关键词参数指定

 默认值永久都生效

def chi(a, b, *food, c='哈哈哈'):
    print(a, b, food, c)

   2,动态接受关键字参数

  在python中可以动态的位置参数,但是,这种情况中能接受位置参数无法接受关键字参数,在python中使用**来接受关键字参数

def func(**kwargs):
    print(kwargs)

func(a=1, b=2, c=3)
func(a=1, b=2)
# {'a': 1, 'b': 2, 'c': 3}
# {'a': 1, 'b': 2}

   这个时候接受的是个dict

顺序的问题,在函数调用的时候,如果先给出关键字参数,则整个参数列表会报错.

def func(a,b,c,d):
    print(a,b,c,d)

func(1,2,c=3,4) # SyntaxError: positional argument follows keyword argument

 关键字参数必须在位置参数后面,否则参数会混乱

所以关键字参数必须在位置参数的后面,由于实参是这个顺序,所以形参接受的时候也是这个顺序,也就是说位置参数必须在关键字参数前面,动态接受关键字参数也要在后面

最终顺序:

  位置参数>*args>默认值参数>**kwargs

接受所有的参数

def func(*args, **kwargs):
    print(args, kwargs)

func('陈润', '周杰伦', lbj="老北京")

 在实参位置上给一个序列,列表,可迭代对象前面加个*表示把这个序列按顺序打散

在形参的位置上的*表示把接收到的参数组合成一个元组

如果是一个字典,那么也可以打散,不过需要用两个

def func(**kwargs):
    print(kwargs)

dic = {'a': 1, 'b': 2}
func(**dic)

 二,命名空间

  在python解释器开始执行之后,就会在内存中开辟一个空间,每当遇到一个变量的时候,就把变量名和值之间的关系记录下来,但是当遇到函数定义的时候,解释器只是把函数读入内存,表示这个函数存在了,至于函数内部的变量和逻辑,解释器不关心,也就是说一开始的时候函数只是加载进来,仅此而已,只有当函数被调用和访问的时候,解释器才会根据函数内部声明的变量来进行开辟变量的内部空间,随着函数执行完毕,这些函数内部变量占用的空间也会随着函数执行完毕被清空.

def fun():
    a = 10
    print(a)
fun()
print(a)  # a不存在了

 我们给存放名字和值的关系的空间起一个名字叫:命名空间.我们的变量在存储的时候就是存储在这篇空间中的.

命名空间分类:

  1,全局命名空间-->我们直接在py文件中,函数外声明的变量都属于全局命名空间

  2,局部命名空间-->在函数中声明的变量会放在局部命名空间

  3,内置命名空间-->存放python解释器为我们提供的名字,list,tuple,str,int这些都是内置命名空间

加载顺序:

  1,内置命名空间

  2,全局命名空间

  3,内置命名空间

a = 10
def func():
    a = 20
    print(a)
    
func()  # 20

 作用域:作用域就是作用范围,按照生效范围来看分为,全局作用域和局部作用域

全局作用域:包含内置命名空间和全局命名空间.在整个文件的任何位置都可以使用(遵循从上到下逐行执行).局部作用域:在函数内部可以使用

作用域命名空间:

  1,全局作用域:全局命名空间+内置命名空间

  2,局部作用域:局部命名空间

我们可以通过globals()函数来查看全局作用域中的内容,也可以通过local()来查看局部作用域中的变量和函数信息

a = 10
def func():
    a = 40
    b = 20
    def abc():
        print('哈哈')
    print(a, b)    # 这里使用的是局部作用域
    print(globals())  # 打印全局作用域中的内容
    print(locals())  # 打印局部作用域中的内容
func()

三,函数的嵌套

  1,只要遇见了()就是函数的调用,如果没有()就不是函数的调用

  2,函数的执行顺序

四,关键字global和nonlocal

  global表示,不再使用局部作用域中的内容,而改用全局作用域中的变量

  nonlocal表示在局部作用域中,调用父级命名空间中的变量

a = 1
def fun_1():
    a = 2
    def fun_2():
        nonlocal a   # a = 2
        a = 3  # fun_1 中的a变成了3
        def fun_3():
            a = 4
            print(a)
        print(a)  # a = 3
        fun_3()  # a = 4
        print(a)  # a = 3
    print(a)  #  a = 2
    fun_2()
    print(a)  # a = 3

print(a)  # 1
fun_1()
print(a)  # 1
# 结果:1,2,3,4,3,3,1

 

posted @ 2018-06-12 17:25  猴里吧唧  阅读(94)  评论(0编辑  收藏  举报