python函数的动态传参.作用域与命名空间
Posted 传盛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python函数的动态传参.作用域与命名空间相关的知识,希望对你有一定的参考价值。
一.动态传参
1.*表示动态传参. 可以接受所有的位置参数传参的时候自动的把实参打包成元组 交给形参
def chi(*food): print(food) chi() # 动态传参可以不传参数 chi(good_food = "胡辣汤") # 关键字传参 chi("胡辣汤", "疙瘩汤", "西红柿鸡蛋汤") chi("大猪蹄子","大汉堡","薯条","圣代","雪顶","拿铁")
2.** 表示接收关键字的动态传参接收到的内容放在字典里
def chi(**food): print(food) chi(good_food = "哈哈", junk_food="呵呵", drink="吼吼") chi("大猪蹄子","大汉堡","薯条","圣代","雪顶","拿铁")
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) # 把一个列表或者元组或者字符串.打散成参数. 传递给形参
2.*, ** : 在形参: 聚合, 实参: 打散 dic = {"张无忌":"倚天屠龙记", "乔峰":"天龙八部", "郭靖":"射雕"} def da(**kwargs): # 动态传参. 接收关键字参数 print(kwargs) # da(张无忌=dic[‘张无忌‘]) da(**dic) # 把字典打散成关键字参数
二.名称空间和作用域
名称空间: 保存名字用的
变量, 函数, 类
1. 内置名称空间:python自己, print, input, len
2. 全局名称空间: 你写的代码从上到下
3. 局部名称空间: 函数, 类, 方法, 其他模块, 对象
作用域
全局作用域
内置 + 全局
局部作用域
局部名称空间
从局部找全局可以. 但是从全局找局部是不可以的
globals() 查看全局作用域中的名字
locals() 查看当前作用域中的名字
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. 函数的嵌套(难点)
每一层都会产生独自的名称空间
例一 # 一个套一个 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.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,写函数,接收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()
以上是关于python函数的动态传参.作用域与命名空间的主要内容,如果未能解决你的问题,请参考以下文章