python函数的动态传参.作用域与命名空间
一.动态传参
1.*表示动态传参. 可以接受所有的位置参数传参的时候自动的把实参打包成元组 交给形参
1 2 3 4 5 6 | def chi( * food): print (food) chi() # 动态传参可以不传参数 chi(good_food = "胡辣汤" ) # 关键字传参 chi( "胡辣汤" , "疙瘩汤" , "西红柿鸡蛋汤" ) chi( "大猪蹄子" , "大汉堡" , "薯条" , "圣代" , "雪顶" , "拿铁" ) |
2.** 表示接收关键字的动态传参接收到的内容放在字典里
1 2 3 4 | def chi( * * food): print (food) chi(good_food = "哈哈" , junk_food = "呵呵" , drink = "吼吼" ) chi( "大猪蹄子" , "大汉堡" , "薯条" , "圣代" , "雪顶" , "拿铁" ) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 1. 顺序 位置 > * args > 默认值参数 > * * kwargs 实参: 位置 > 关键字 位置, * args, 默认值参数, * * kwargs 无敌传参 顺序 位置 > * args > 默认值参数 > * * kwargs def func( * args, * * kwargs): print (args, kwargs) func( 1 , 2 , "哈哈" , 3 , 4 , 5 ,a = 6 ,b = 7 ,c = 8 ,d = 9 , e = 18 ) lst = [ "火腿肠" , "方便面" , "有调料包" , "被捏碎了" , "韭菜" , "大白菜" ] def chi( * food): # 形参上的* : 动态接收位置参数 print (food) # 把列表中的所有食物传递给chi chi( * lst) # 把一个列表或者元组或者字符串.打散成参数. 传递给形参 |
1 2 3 4 5 6 | 2. * , * * : 在形参: 聚合, 实参: 打散 dic = { "张无忌" : "倚天屠龙记" , "乔峰" : "天龙八部" , "郭靖" : "射雕" } def da( * * kwargs): # 动态传参. 接收关键字参数 print (kwargs) # da(张无忌=dic['张无忌']) da( * * dic) # 把字典打散成关键字参数 |
二.名称空间和作用域
名称空间: 保存名字用的
变量, 函数, 类
1. 内置名称空间:python自己, print, input, len
2. 全局名称空间: 你写的代码从上到下
3. 局部名称空间: 函数, 类, 方法, 其他模块, 对象
作用域
全局作用域
内置 + 全局
局部作用域
局部名称空间
从局部找全局可以. 但是从全局找局部是不可以的
globals() 查看全局作用域中的名字
locals() 查看当前作用域中的名字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | a = 10 def chi(): a = 20 print (a) print (a) # 10 chi() # 20 print (a) # 10 def print ( * args): pass # print(args) # maximum recursion depth exceeded def func(): print ( "呵呵" ) func() def chi(): p = 30 print ( locals ()) # {'p': 30} locals()可以查看局部作用域中的内容 print (p) chi() print ( locals ()) # 查看当前作用域中的名字 print ( globals ()) a = 10 # 全局 b = 20 print ( globals ()) # 查看全局作用域中(内置+全局)的内容 |
3. 函数的嵌套(难点)
每一层都会产生独自的名称空间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 例一 # 一个套一个 def outer(): print ( "我是outer" ) # 在函数内部声明的函数, 只能在函数内部访问 def inner(): print ( '我是inner' ) inner() print ( "我是outer_end" ) outer() 例二 def fun2(): print ( 222 ) def fun3(): print ( 666 ) print ( 444 ) fun3() print ( 888 ) print ( 33 ) fun2() print ( 555 ) 33 222 444 666 888 555 |
4. nonlocal global
global: 在局部引入全局的内容, 可以升华一个变量为全局变量
nonlocal : 在局部, 引入上一层名称空间中的变量, 如果没有, 继续上一层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | 1.global a #直接从全局把变量引入进来,可以创建(升华)一个局部变量为全局变量 例一 a = 10 def func(): global a # 直接从全局把变量引入进来 a = 20 # a = 20 # 并没有改变全局变量, 创建了一个自己的变量 # 全局变量在局部, 可以用, 但是, 不能改 # a = a + 10 print (a) func() print (a) 例二 def func(): global a # 可以创建(升华)一个局部变量为全局变量 a = 30 func() print (a) 2.nonlocal 在局部, 引入上一层名称空间中的名字. 如果上一层没有, 继续上一层 ..... 例一 def outer(): a = 10 def inner(): nonlocal a a = 20 print (a) print (a) # 10 inner() # 20 print (a) # 20 outer() 例二 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) # 答案1234331 |
三.作业
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | 1 ,写函数,接收n个数字,求这些参数数字的和。(动态传参) def num( * args): sum = 0 for i in args: sum + = i return sum print (num( 1 , 2 , 3 , 4 )) 2 ,读代码,回答:代码中,打印出来的值a,b,c分别是什么?为什么? a = 10 b = 20 def test5(a,b): print (a,b) c = test5(b,a) print (c) #20 10没有返回值所以最后打印的值是空 3 ,读代码,回答:代码中,打印出来的值a,b,c分别是什么?为什么? a = 10 b = 20 def test5(a,b): a = 3 b = 5 print (a,b) #3 5 c = test5(b,a) print (c ) # 空 print (a,b) #10 20 4 ,写函数,传入函数中多个实参(均为可迭代对象如字符串,列表,元祖,集合等),将每个实参的每个元素依次添加到函数的动态参数args里面. 例如 传入函数两个参数[ 1 , 2 , 3 ] ( 22 , 33 )最终args为( 1 , 2 , 3 , 22 , 33 ) def func(lis,tu): for i in list (tu): lis.append(i) return tuple (lis) print (func([ 1 , 2 , 3 ],( 22 , 33 ))) 5 ,写函数,传入函数中多个实参(实参均为字典),将每个实参的键值对依次添加到函数的动态参数kwargs里面. 例如 传入函数两个参数{‘name’:’alex’} {‘age’: 1000 }最终kwargs为{‘name’:’alex’ ,‘age’: 1000 } def func( * * kwargs): print (kwargs) func( * * { "name" : "alex" }, * * { "age" : 1000 }) 6 , 下面代码成立么?如果不成立为什么报错?怎么解决? 7.1 a = 2 def wrapper(): print (a) wrapper() 成立 7.2 a = 2 def wrapper(): a + = 1 print (a) wrapper() 不成立,局部空间无法直接调用全局空间中的变量 7.3 def wrapper(): #第一步def直接调用,第二定义,第三执行,第四部 a = 1 def inner(): print (a) inner() wrapper() 可执行 7.4 def wrapper(): a = 1 def inner(): a + = 1 print (a) inner() wrapper() 局部空间的变量不能直接调用和改变外层变量 8 ,写函数,接收两个数字参数,将较小的数字返回. def func(a,b): if a>b: return b else : return a print (func( 3 , 4 )) return a if a<b else b print (func( 3 , 4 )) 方案二 def func(a,b): return a if a<b else b print (func()) 9 ,写函数,传入n个数,返回字典{‘ max ’:最大值,’ min ’:最小值} 例如:min_max( 2 , 5 , 7 , 8 , 4 ) 返回:{‘ max ’: 8 ,’ min ’: 2 }(此题用到 max (), min ()内置函数) def func( * args): print ( min (args)) print ( max (args)) return { '最大值' : max (args), "最小值" : min (args)} print (func( 2 , 4 , 7 , 8.0 )) 10 ,写函数,传入一个参数n,返回n的阶乘 例如:cal( 7 ) 计算 7 * 6 * 5 * 4 * 3 * 2 * 1 def func(n): s = 1 for i in range ( 1 ,n + 1 ): s * = i return s print (func( 5 )) 11 写函数,返回一个扑克牌列表,里面有 52 项,每一项是一个元组 例如:[(‘红心’, 2 ),(‘草花’, 2 ), …(‘黑桃’,‘A’)] pai = [] s = [ "红桃" , "方块" , "黑桃" , "梅花" ] t = [ "A" , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '8' , '10' , 'J' , 'Q' , 'K' ] for i in s: for j in t: pai.append((i,j)) print (pai) print ( len (pai)) 12 有如下函数: def wrapper(): def inner(): print ( 666 ) wrapper() 你可以任意添加代码,用两种或以上的方法,执行inner函数. def wrapper(): def inner(): print ( 666 ) # return inner() #1 # inner() #2 wrapper() |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 《HelloGitHub》第 108 期
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单
· C# 13 中的新增功能实操
· Supergateway:MCP服务器的远程调试与集成工具