[2022.7.4] 函数概要讲解 2

函数概要内容介绍

*与**在实参中的作用

def func(*args,**kwargs):
    print(arge)
    print(kwargs)
 """上述函数定义是在模拟一个函数定义 没有任何的实际参数 是模拟的形参 任何函数调用都可以 """
函数调用示例如下:
func()  # ()  {}
func(22,3,44,44,55)  # (22, 3, 44, 44, 55)  {}
func([22,3,44,44,55])  # ([22, 3, 44, 44, 55],)  {}
"""上述是用不同的函数调用实参 产生的结果"""

# 如果调用函数时 想用定义好的变量名的数据值 一个一个的调用 传值到形参中 用之前学习到的索引取值就比较繁琐 可以用 * 加入的实参中 就可以一步做到
之前的方式:
l1 = [1, 2, 3, 4, 5, 6]
func(l1[0], l1[1], l1[2], l1[3], l1[4], l1[5])  # (1, 2, 3, 4, 5, 6) {}
# 上述用到的是索引取值 如果数据值量大的情况下 索引取值就比较繁琐 耗费时间 
加 * 号的方式:
l1 = [1, 2, 3, 4, 5, 6]
func(*l1)  # (1, 2, 3, 4, 5, 6) {}
'''列表传值'''
s2 = 'jason'
func(*s2)  # ('j', 'a', 's', 'o', 'n')  {}
'''字符串传值'''
d3 = {'name': 'jason', 'age': 18}
func(*d)  # ('name', 'age') {}
'''字典传值'''

"""以上在实参中加入一个 * 号的作用 其实就类似于for 循环 循环取值传值 """

# 加入两个 ** 号的作用我们来看一下
d4 = {'name': 'jason', 'age': 18}
func(**d4)  # ()  {'name': 'jason', 'age': 18}
""" 相当于关键字传值 
func(name='jason', age=18)  # ()  {'name': 'jason', 'age': 18}
其效果是一样的
"""
区分:
''' * 号 在形参中 是替代参数 把实参中多余传输的值(位置参数) 用元组的形式呈现出来
** 号 在在形参中 是替代参数 把实参中多余传输的值(关键字参数) 用字典的形式呈现出来

 * 号 在实参中 相当于用 for 循环是把多个数据值一次性传输到函数中  等同于位置实参
 ** 号 在实参中 用字典 k v 值方式 传输给函数 等同于关键字实参 

'''

命名关键字参数

def func(a,b,*args):
    print(a,b,args)
func(1,2)  # 1 2 ()
func(1,b=2)  # 1 2 ()
func(b=1,a=2)  # 2 1 ()
func(1,213,23,1213,12312)  # 1 213 (23, 1213, 12312)
'上述正常是正常的函数调用示例'

"""
现在需要在下述的函数中 形参 c 传输值是55 """
def func(a,b,*args,c):
    print(a, b, args, c)
func(1,22,55)  # 报错
func(55,55,55,55,55,55)  # 报错
# 必须要使用到关键值传值
func(1,2,c=55)  # 1 2 () 55
# 如果形参中还有**kwargs(关键字参数) 那c必须在它的前面
def func(a,b,*args,c,**kwargs):
    pass
func(1,2,3,4,5,6,c=55,name='jason')

名称空间

简单来说就是在计算机中用来存放各个变量名与数据值绑定观关系的地方
"""
之前的学习过程中我们用到的例如
		name = 'make'
	是把  make 这个数据值和 name 这个变量名 绑定在一起 存入到名称空间 方便后期使用起来方便 直接用name 这个变量名直接在名称空间中去搜索对应的数据值就可以了
	del = name
	删除这个变量后 删除的不是数据值 make 是name 和 make 的绑定关系 从而使其变成游离态
"""
名称空间的分类
1.内置名称空间
2.全局名称空间
3.局部名称空间

1.1(内置名称空间)就是在python解释器定义好的  
在平常的使用中类似于  open() input() print() len()...
2.1(全局名称空间) 就是在python中 代码在运行其中 只要是里面出现的名字 都会存贮到该空间
	# 普通代码里面的变量名
    # 分支结构里的变量名
    # 循环结构里的变量名
    # 定义函数 调用函数里 的函数名
3.1(局部名称空间)定义函数后 函数体代码中用到的变量名存入的空间


&&:名称空间的存活周期
	内置名称空间:只要python运行 就在待命 随时等待您的命令 关闭解释器 结束运行就结束了
    全局名称空间:一个py文件只要在运行中 就一致存活  关闭py文件就结束
    局部名称空间:函数体代码运行 调用时就存活 运行结束 就结束

名字的查找顺序

"""
把内置 全局 局部 3个名称空间排序的顺序是:
	局部 > 全局 > 内置
此顺序是固定的 不可变的  
查找名字的时候 要看好想要找的这个名字 在哪个名称空间  先确定好名称空间 然后在按照 上面这个顺序去查找 
顺序不可逆 
当前在局部 只能在局部 > 全局> 内置 查找
当前在全局 只能在全局 >内置 查找
"""

名称空间的作用域

1.内置名称空间:全局名称空间:
	前者是python解释器定义的名字
    后者是在py文件中用到的名字
在程序任意的位置都可以是使用都有作用 无限制(全局有效)
2.局部名称空间:
    只有在各自局部的空间(各自的函数代码体)才能使用 才作用(局部有效)

局部名称空间复杂的情况

1.在各自的局部名称空间 默认的情况下 彼此之间的名字 互不干涉

def func():
    a = 1
    print(b)


def func1():
    b = 2
    print(a)


func()
func1()

2.特殊情况
# name = 'make1'
# def func1():
#     name = 'make2'
#     def func2():
#         name = 'make3'
#         def func3():
#             name = 'make4'
#             print(name)  #先找func3 局部 找不到在往外找func2局部 以此类推: > 全局 > 内置
#         func3()
#     func2()
# func1()


def func():
    name = 'make2'  # 正常代码顺序
    print(name)
    name = 'make2'  # 不符合代码抒写顺序

func()
& 函数在定义阶段 局部空间内函数代码体里的名字查找顺序就已经固定好了

关键字global与nonlocal的使用

wages = 100
def func():
    wages = 110

func()
print(wages)  # 100
"""上述情况下 局部空间里的 wages 不影响全局空间里的 wages 的 使用 互不干涉
如果想让局部空间里的名字干涉修改全局空间的名字 
需要用到关键字 global 修改"""
wages = 100
def func():
    global wages
    wages = 110
    print(wages)


func()  # 110
print(wages)  # 110
""" 上述以局部修改全局"""

"""局部修改全局如果是不可变类型 需要用到global
可变类型 如 列表 字典 集合 则不需要用到golbal修改
"""
def func1():
    p = 1
    l1 = [2,3,4]

    def func2():
        nonlocal p

        p = 2
        l1.append(99)

    func2()
    print(p)  # 1 # 2
    print(l1)  # [12, 32, 43, 99]
func1()
# 在正常情况下 p = 1  想让 func2 局部中 的 p = 2 改变 func1 局部中 p 的值 需要用到 关键字 nonlocal 
# 在func2 中 加入关键字 nonlocal  就改变了func1 中 p 的值

# 局部修改全局用golbal(可变类型除外)
# 局部修改局部用nonlocal(可变类型除外)

函数名的多种使用方式

1.函数名也可以绑定变量名,多次赋值 使用和变量名差不多

# def func():
#     print('from func')
# name = func
# print(name)  # <function func at 0x01778778>
# name()  # from func
# name1 = name
# print(name1)  # <function func at 0x01A18778>
# name1()  # from func

2.函数名也可以当作函数的实参(相互调用)
# def func():
#    print('from func')
# def index(a):
#    print(a)
# index(123)  # 123
# name = 'make'
# index(name)  # make
# index(func)  # <function func at 0x022DB070>
# a = func
# a()  # from func

3.函数名还可以充当返回值
# def func():
#     print('from func')
# def index():
#     return func  # func 函数名当返回值
# res = index()  # 接收返回值 赋值给res
# print(res)  # <function func at 0x016CB070> # 得到函数名func的函数代码体存储地址
# res()  # from func

 4.函数名还可以当做容器类型里面的数据值
# def func():
#     print('from func')
# l1 = [1,23,43,func,45,454]
# print(l1[3])  # <function func at 0x02298778> # 得到函数名func的函数代码体存储地址
# l1[3]()  # from func  后面加个括号就能调出函数
posted @   W日常  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示