函数的进阶

函数的动态参数

动态接收位置参数(*args)

动态接收关键字参数(**kwargs)

def func(*args,**kwargs):
    print(args,kwargs)
func("马化腾","马云",wtf="胡辣汤")
#('马化腾', '马云') {'wtf': '胡辣汤'}  结果是一个tuple 和一个dict
#**********动态传参的另一种形式
def fun(*args):
    print(args)
lst = [1,4,7]
fun(lst[0],lst[1],lst[2])
#(1, 4, 7)
def fun(
*args): print(args) lst = [1,4,7] fun(lst) #([1, 4, 7],) 直接传一个list进去的话,得到的就是一个元组
def fun(
*args): print(args) lst = [1,4,7] fun(*lst) #(1, 4, 7) 用*把一个列表按顺序打散,得到的和按索引传的结果一样
def fun(
*args): print(args) s="臣妾做不到" #字符串也可以打散(可迭代对象) fun(*s) #('', '', '', '', '')

def func(*food): #
print(food) #(1, 2, 3, 4, 5, 6)
lst=[1,2,3,4,5,6]
func(*lst)
总结:在实参位置上给一个序列,列表,可迭代对象前面加上*表示把这个序列按照顺序打散

参数位置排列 (位置参数     *args     默认值参数     **kwargs)

函数的命名空间

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

在函数的运行中开辟的临时的空间叫做局部命名空间.

函数执行完毕后,函数内部变量占用的空间也会随着函数执行完毕而

命名空间有三种:   全局命名空间    局部命名空间    内置命名空间

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

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

a = 10 #全局命名空间的内容
def fn(): # fn也在全局命名空间
    b = 20 #局部命名空间
    print(a)
def gn(): #全局命名空间
    print(a)
fn()
gn()

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

    全局作用域 包含内置名称空间和全局名称空间

    局部作用域 包含局部名称空间 只在局部范围内生效

a = 10 #全局命名空间的内容
def fn(): # 全局命名空间
    a = 30 #局部命名空间
    b = 20 #局部命名空间
    def gn(): #局部命名空间
        print("哈哈")
    print(a,b)
    print(globals()) #打印全局作用域中的内容  {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x012B73B0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/PycharmProjects/oldboy_2/day11/名称空间.py', '__cached__': None, 'a': 10, 'fn': <function fn at 0x013DC4B0>}
    print(locals()) #打印局部作用域中的内容   {'gn': <function fn.<locals>.gn at 0x013DC468>, 'b': 20, 'a': 30}
fn()

嵌套函数

函数可以相互嵌套

#嵌套函数
def outer():
    print("haha")
    def inner_1():
        print("呵呵")
        def inner_1_1():
            print("嘻嘻")
        inner_1_1()
        print("吼吼")
    def inner_2():
        print("嘿嘿")
    inner_2()
    inner_1()
outer()
#haha
#嘿嘿
#呵呵
#嘻嘻
#吼吼

global 和 nonlocal

global:

  1,声明一个全局变量。

  2,在局部作用域想要对全局作用域的全局变量进行修改时,需要用到 global(限于字符串,数字)

a = 100
def func():
    global a # 加个global表示不在局部创建这个变量了,而是直接使用全局的a
    a = 28
    print(a) #28
func()
print(a) #28

 ps:对可变数据类型(list,dict,set)可以直接引用不用通过global。

lst = ["马化腾","刘嘉玲","詹姆斯"]
def func():
    lst.append("马云") #对于可变数据类型可以访问,但是不能赋值(针对字符串和数字而言)
    print(lst) #['马化腾', '刘嘉玲', '詹姆斯', '马云']

func()
print(lst) #['马化腾', '刘嘉玲', '詹姆斯', '马云']

nonlocal:

  1,不能修改全局变量。

  2,在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。

#对比一下有nonlocal 和 没有nonlocal
a = 10
def func1():
    a = 20
    def func2():
        nonlocal a   #有nonlocal 当func2()执行完毕的时候,a的值从函数中跳出,指向def func2()外层的a
        a = 30
        print(a)#30
    func2()
    print(a)#30
func1()


a = 10
def func1():
    a = 20
    def func2():
        a = 30
        print(a)#30    #没有nonlocal 在func2()跳出循环的时候,a的值从函数中跳出时指向函数外层的 a=20                    
    func2()
    print(a)#20
func1()
   
a = 10
def outer():
    a = 30
    def inner(): # 在inner中改变a的值, 寻找外层函数中离他最近的那个变量
        nonlocal a
        a = 20
        print(a) #20
    inner()
    print(a)#20
outer()
print(a)#10
原文地址:https://www.cnblogs.com/kenD/p/9450855.html