函数2——*args/**kwargs、作用域、函数的嵌套、关键字globa和nonlocal、函数的注释

一、动态参数

  1、位置参数的动态参数:*args

在参数位置编写*表示接收任意的内容
def chi(*food):
    print("我喜欢吃:",food)
chi("川菜","料理")

#结果:
我喜欢吃: ('川菜', '料理')   #多个参数传递进去,收到的是元组tuple

#动态接收参数的时候,动态参数必须在位置参数后面
def chi(a,b,*food):
    print("我喜欢吃:",a,b,food)
chi("大米","面条","川菜","料理","湘菜")
#结果:
我喜欢吃: 大米 面条 ('川菜', '料理', '湘菜')


#默认值参数放在动态参数后面,(顺序:位置参数,动态参数*,默认值参数)
def chi(a,b,*food,c="川菜"):
    print("我喜欢吃:",a,b,food,c)
chi("大米","面条","鲁菜","料理","湘菜")
chi("包子","小米粥","花生","毛血旺","酸辣鸡胗",c="泡菜炒饭")
#结果:
我喜欢吃: 大米 面条 ('鲁菜', '料理', '湘菜') 川菜   #默认值生效
我喜欢吃: 包子 小米粥 ('花生', '毛血旺', '酸辣鸡胗') 泡菜炒饭   #替换掉默认值

  2、关键字参数的动态参数:**kwargs  (在python中使用**来接收动态关键字参数)

def func(**kwargs):
    print(kwargs)
func(赵丽颖 = "花千骨",霍建华 = "白子画",马可 = "杀阡陌")
func(a = 1,b = 2,c = 3)
#结果:
{'赵丽颖': '花千骨', '霍建华': '白子画', '马可': '杀阡陌'}
{'a': 1, 'b': 2, 'c': 3}   #接收到的结果是一个dict类型的数据

  3、顺序:位置,*args,默认值,**kwargs

def func(a,b,*args,c="谢逊",**kwargs):
    print(a,b,args,c,kwargs)
func("张三丰","灭绝师太","张无忌","周芷若","赵敏",倚天屠龙记 = "倚天剑,屠龙刀")
func("张三丰","灭绝师太","张无忌","周芷若","赵敏",c = "金毛狮王",倚天屠龙记 = "倚天剑,屠龙刀")
#结果:
张三丰 灭绝师太 ('张无忌', '周芷若', '赵敏') 谢逊 {'倚天屠龙记': '倚天剑,屠龙刀'}
张三丰 灭绝师太 ('张无忌', '周芷若', '赵敏') 金毛狮王 {'倚天屠龙记': '倚天剑,屠龙刀'}  #可以替换掉默认值

  4、在形参上*聚合,**聚合

     在实参上*打散,**打散

#接收所有参数
def func(*args,**kwargs):
    print(args,kwargs)
func("张三丰","张无忌",a = "周芷若",b = "赵敏")
#结果:
('张三丰', '张无忌') {'a': '周芷若', 'b': '赵敏'}


#动态参数的另一种传参方式:
def func(*args):
    print(args)
lis = [1,5,8]
func(lis[0],lis[1],lis[2])  #使用这种方式太麻烦

func(*lis)   #使用*可以把一个列表顺序打散
s = "我喜欢赵丽颖"
func(*s)     #字符串也能被打散(可迭代对象)
#结果:
(1, 5, 8)
(1, 5, 8)
('', '', '', '', '', '')
@在实参位置上给一个序列,可迭代对象前面加一个*表示把这个序列按顺序打散

 

二、命名空间和作用域

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

def func():
    a = 10
    print(a)
func()
print(a)  # a不存在了已经

 

  1、命名空间:

    a、内置命名空间:python解释内部运行时的变量函数

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

    b、全局命名空间:在py文件中直接声明出来的变量函数

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

    c、局部命名空间:在函数内部声明的变量和函数

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

  2、加载顺序和取值顺序:

     加载顺序:1、内置命名空间

          2、全局命名空间

          3、局部命名空间(函数被执行的时候)

     取值顺序:1、局部命名空间

          2、全局命名空间

          3、内置命名空间

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

 

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

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

        内置命名空间 + 全局命名空间

    b、局部作用域:在函数内部可以使用

        局部命名空间

    globals()查看全局作用域中的内容

    locals()查看当前作用域中的变量和函数信息

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

三、函数的嵌套

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

  2、函数的执行顺序

1、调用
def func1():
    print(111)
def func2():
    print(222)
func2()
print(111
#结果:
222
111 -->这是最后print(111)的结果   func()没有被调用,不会有结果


2、嵌套:
def func2():
    print(222)
    def func3():
        print(666)
    print(444)
    func3()
    print(888)
print(333)
func2()
print(555)
#结果:
333
222
444
666
888
555

def outer():
print("哈哈")
def inner1():
print("呵呵")
def inner1_1():
print("嘻嘻")
inner1_1()
print("吼吼")
def inner2():
print("嘿嘿")
inner2()
inner1()
outer()
#结果:
哈哈
嘿嘿
呵呵
嘻嘻
吼吼

 

四、关键字globa和nonlocal

  1、global:把全局变量拿到局部来用

a = 100
def func():
    global a  #引用全局变量
    a = 20    #改变全局变量的值,把全局中的a重新赋值成20
    print(a)
func()
print(a)
#结果:
20
20

 

  2、nonlocal:把离他最近的一层的变量拿过来,不会找全局变量

#没用nonlocal时
a = 10
def func1():
    a = 20
    def func2():
        a = 30
        print(a)
    func2()
    print(a)
func1()
#结果:
30
20


#用了nonlocal时
a = 10
def func1():
    a = 20
    def func2():
        nonlocal a
        a = 30
        print(a)
    func2()
    print(a)
func1()
#结果:
30
30
a = 1
def fun_1():
    a = 2
    def fun_2():
        nonlocal a
        a = 3
        def fun_3():
            a = 4
            print(a)
        print(a)
        fun_3()
        print(a)
    print(a)
    fun_2()
    print(a)
print(a)
fun_1()
print(a)
#结果:
1
2
3
4
3
3
1


 五、函数的注释:

def foo(food,drink):
    '''
    这里是函数的注释,先写一下当前这个函数是干什么的。
    :param food: 参数food是什么意思
    :param drink: 参数drink是什么意思
    :return: 返回的参数
    '''
    print(food,drink)
    return "very good"

 

posted @ 2018-07-17 20:54  LW-5208  阅读(219)  评论(0)    收藏  举报