day010 动态传参、函数嵌套、命名空间、作用域

一、函数参数-动态传参(形参的动态接收)

1、形参分为

顺序:位置 > *args > 默认 > **kwargs
1.位置参数
2.默认参数
3.动态传参(*args, **kwargs)

1. *args: 动态接收位置参数

fe:

def chi(*food):
    print("我要吃", food)
chi("⼤⽶饭", "⼩⽶饭")
#结果:
#我要吃 ('⼤⽶饭', '⼩⽶饭') # 多个参数传递进去. 收到的内容是元组tuple

2. **kwargs:动态接收关键字参数

顺序: 位置 > *args > 默认值 > **kwargs
fe:
def func(**kwargs):
 print(kwargs)
func(a=1, b=2, c=3) #输出为一个dict
func(a=1, b=2)
# 结果:
# {'a': 1, 'b': 2, 'c': 3}
# {'a': 1, 'b': 2}

2、(args, *kwargs)组合可以无敌传参

fe:可以接收所有参数

def func(*args, **kwargs): #无敌传参
    print(args, kwargs)
func("麻花藤","⻢晕",wtf="胡辣汤")

3、(, *

*, ** 在形参位置: 聚合
*, ** 在实参位置: 打散

fe1:args

def fun(*args): #输出为元组
    print(args)
lst = [1, 4, 7]
fun(lst[0], lst[1], lst[2]) #需要手动将列表元素手动输入

fun(*lst) # 可以使⽤*把⼀个列表按顺序打散
s = "⾂妾做不到"
fun(*s) # 字符串也可以打散, (可迭代对象)
#结果为:
(1, 4, 7)
('⾂', '妾', '做', '不', '到')

fe2: *, *kwargs

def fun(**kwargs): #输出为字典
    print(kwargs)
dic = {'a':1, 'b':2}
fun(**dic)  #将字典里面的键值对逐一输入
#结果:{'a': 1, 'b': 2}

2、实参:

顺序:位置 > 关键字
1. 位置参数
2. 关键字参数
3. 混合参数

二、命名空间

1、命名空间: 保存名字用的

存放名字和值的关系的空间起⼀个名字叫: 命名空间.
 我们的变量在存储的时候就是存储在这片空间中的.
变量, 函数, 类

1.加载顺序:

内置 > 全局 > 局部
1. 内置名称空间:python自己的,存放python解释器为我们提供的名字, list, tuple, str, int这些都是内置命名空间
2. 全局名称空间: 你写的代码从上到下,我们直接在py⽂件中, 函数外声明的变量都属于全局命名空间
3. 局部名称空间: 在函数中声明的变量会放在局部命名空间;函数, 类, 方法, 其他模块, 对象

2.取值顺序

局部 > 全局 > 内置
fe:取值顺序
a = 10
def func():
    a = 20  #先取值局部命名空间的
    print(a)
func() # 20

2、作用域

作⽤域: 作⽤域就是作⽤范围, 按照⽣效范围来看分为: 全局作⽤域和局部作⽤域
从局部找全局可以. 但是从全局找局部是不可以的

1.全局作用域:

包含内置命名空间和全局命名空间. 在整个⽂件的任何位置都可以使⽤(遵循从上到下逐⾏执⾏).
内置 + 全局

2.局部作用域:

局部作⽤域: 在函数内部可以使⽤.
局部名称空间

3.查看作用域的内容

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

三、函数的嵌套(难点)

每一层都会产生独自的局部名称空间
只有遇到了()就是函数的调用,如果没有()就不是函数的调用

1.函数执行的顺序

fe:

def fun1():
    print(111)

def fun2():
    print(222)
    fun1()

fun2() #先执行fun2(),再fun1()
print(111)

2.函数的嵌套

fe:

def fun2():
    print(222)
    def fun3():
        print(666)
    print(444)
    fun3()
    print(888)
print(33)
fun2()
print(555)

四、关键字:nonlocal和global

1、global

1.在局部引入全局的内容, 可以对引入的全局变量进行修改
global表⽰. 不再使⽤局部作⽤域中的内容了. ⽽改⽤全局作⽤域中的变量
2.可以升华一个变量为全局变量(即没有时可以在局部创建一个新的出来),这个变量为全局变量
3.对于可变数据类型可以直接进⾏访问. 但是不能改地址. 说⽩了. 不能赋值
fe1:global表示在局部中使用全局变量,并且可以对全局变量修改
a = 100
def func():
    global a # 加了个global表示不再局部创建这个变量了. ⽽是直接使⽤全局的a
    a = 28
    print(a) #28
func()
print(a) #28
fe2:global对可变数据的直接访问
lst = ["麻花藤", "刘嘉玲", "詹姆斯"]
def func():
    lst.append("⻢云云") # 对于可变数据类型可以直接进⾏访问. 但是不能改地址. 说⽩了. 不能赋值
    print(lst)
func()
print(lst)

2、nonlocal

1.在局部, 引入(父级)上一层名称空间中的变量, 如果没有, 继续上一层......
2.引入父级变量后,可以对变量进行修改
fe1:nonlocal调用父级变量,并修改
a = 10
def func1():
    a = 20
    def func2():
        nonlocal a
        a = 30
        print(a)  #30
    func2()
    print(a)  #30
func1()
结果:
加了nonlocal
30
30
不加nonlocal
30
20
fe2:函数多层嵌套,这题做对了,就过关
a = 1
def fun_1():
    a = 2
    def fun_2():
        nonlocal a
        a = 3
        def fun_3():
            a = 4
            print(a) #4
        print(a)  #3
        fun_3()
        print(a) #3
    print(a) #2
    fun_2()
    print(a) #3

print(a) #1
fun_1()
print(a) #1
原文地址:https://www.cnblogs.com/yipianshuying/p/9879097.html