首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python3中函数进阶

1:动态传参

首先看下下列代码,实现对2个整数进行求和 运算;如果只有两个参数的话,函数m_sum是能够很好地运行,但是如果要对3个,4个甚至更多的整数进行求和运算时,函数m_sum将不能工作。

def m_sum(a,b): ret = a + b return ret print(m_sum(1,3))

那么要怎样定义函数才能接收多个个数可变的参数呢,在python中提供了动态传参,即可以接收任意个参数,代码如下:

def m_sum(*args): print(args) ret = 0 for x in args: ret += x return ret print(m_sum(1,3))print(m_sum(1,3,4,5)) """(1, 3)4(1, 3, 4, 5)13"""

Python中的动态传参:

*args 位置参数 接收到的是元组;把位置参数没有接收的,都被收集到args中;

**kwargs 关键字的动态传参, 接收到的是字典;把关键字参数没有变接收的,都被收集到kwargs中;

"""形参声明顺序:位置 *args 默认值 **kwargs ;不能是其它顺序;"""def func( a,b,*args,c = 100,**kwargs ): print(a, b, c, args,kwargs) """1:调用实参传递顺序:位置参数,关键字参数;(可以全部是关键字参数;但不能全部是位置参数)2:其中位置参数 传递给 a,b,*args;a,b被赋值后剩下的以元组的形式给args;3:关键字参数传递给 c = 100,**kwargs;匹配默认参数之后,剩下的以字典的形式给kwargs;4:关键字参数之后不能有位置参数传递;5:*args之后的默认值参数必须以关键字参数的形式传递,不然会永远都接收不到值,因为多余的位置参数会传递给args;"""# 1,2,3,4,5,6,8 给a,b,*args# a2 = 20,c = 200 给 c = 100,**kwargsfunc(1,2,3,4,5,6,8,a2 = 20,c = 200) # 输出 1 2 100 (3, 4, 5, 6, 8) {'a2': 20} # 1, 2, 5, 给a,b,*args# aa="hello", bb="python", cc="ixusy88" 给 c = 100,**kwargsfunc(1, 2, 5, aa="hello", bb="python", cc="ixusy88") # 输出 1 2 10 (5,) {'aa': 'hello', 'bb': 'python', 'cc': 'ixusy88'} #下面的调用方式是错误的,关键词参数之后不能有位置参数# func(bb="python",1, b = 2, c=5, aa="hello", cc="ixusy88") # 全部都是关键字参数func(bb="python",a = 1, b = 2, c=5, aa="hello", cc="ixusy88") # 1 2 5 () {'bb': 'python', 'aa': 'hello', 'cc': 'ixusy88'}

无敌模式. 所有的参数都能接收

def func(*args, **kwargs): print(args) print(kwargs)

"*" 和"**" :

在函数定义中:收集参数

在函数调用中:解包参数

# 函数定义的时候:# *args :收集所有位置参数 ,最终会收集为一个元祖# **kwargs:收集所有关键字参数,最终会收集为一个字典def func(*args, **kwargs): print(args) print(kwargs) func(1,2,3,a=20,b=30) """输出:(1, 2, 3){'a': 20, 'b': 30}""" # 在函数调用的时候:# * : 会解包参数的集合,它会将序列解包成相应的参数# ** :会以键/值对的形式把一个字典解包为独立的关键字参数 lst = [1,2,3]# 作为一个参数传递func(lst) """输出:([1, 2, 3],){}""" # 把lst中的元素作为值传递func(*lst) # 与 func(1,2,3) 调用是一样的"""输出:(1, 2, 3){}""" dic = {'name':'ixusy88','age':18}# 作为一个参数传递func(dic) """输出:({'name': 'ixusy88', 'age': 18},){}""" # 把dic中的键/值对解包为关键字传递func(**dic) # 与 func(name='ixusy88',age=18) 调用是一样的"""输出:(){'name': 'ixusy88', 'age': 18}"""

2:作用域

Python中有如下作用域:

内置作用域(B):在内置名称模块中预先赋值好的名称(就是在builtins模块中定义的)。

全局作用域(G):在一个模块文件顶层被赋值的变量,或者在文件中def 语句内通过global 关键字声明的变量。全局作用域仅限于单个文件。

外层作用域(E):在外层函数(def或lambda)的局部作用域中的变量,由内向外。

局部作用域(L):在一个函数(def或lambda)中被赋值的变量,不包括那些被global关键字声明的变量。

Python中一个变量的作用域总是由它在代码中被赋值的位置决定的,而与函数调用无关。

一个变量可以在3个不同的地方被赋值:

a:在def内赋值,它对该函数而言是局部的;

b:在外层的def中赋值,对于内层函数来说,它是非局部的;

c:在所有def外赋值,它对整个文件来说是全局的;

变量名解析规则:LEGB

LEGB :局部作用域(L)  ---->  外层作用域(E) ---->   全局作用域(G)  ---->  内置作用域(B)  ,即对一个变量的引用,会由内到外来查找;

# 全局作用域a = 100 def func(): # print('1---a=',a) # 此处对a的引用会报错,因为a是局部的,引用之前没有进行赋值操作。 a = 200 # 此处的a为func的局部作用域,对其赋值,a指向了新的对象,不影响全局作用域中的a print('2---a=',a) func()print('3---a=',a) """2---a= 2003---a= 100""" # global : 在函数局部中声明变量为全局的b = 100def func(): global b # 在局部作用域中 声明全局变量b, print('1---b=',b) # 修改之前 b = 200 # b是全局变量,对其修改就是修改全局作用域中的b print('2---b=',b) func()print('3---a=',b) """1---b= 1002---b= 2003---a= 200"""

3:函数嵌套

在Python中可以对函数进行嵌套,即在函数中也可以定义函数:

# 函数可以互相嵌套def outer(): def inner(): print("in--inner") print("in--outer") inner() outer() """输出结果in--outerin--inner""" # 可以多层嵌套def outer(cnt): print(' '*cnt,"outer--开始") def inner_1(cnt): print(' '*cnt,"inner_1--开始") def inner_2(cnt): print(' '*cnt,"inner_2--") inner_2(cnt+4) print(' '*cnt,"inner_1--结束") inner_1(cnt + 4) print(' '*cnt,"outer--结束") outer(0) """输出结果: outer--开始 inner_1--开始 inner_2-- inner_1--结束 outer--结束"""

nonlocal 引入上层局部变量:

# global 引入全局变量, 可以定义全局变量# nonlocal 引入局部中离他最近的外层变量 a = 100def outer(): a = 200 # 此处的a为 outer的局部变量 def inner(): nonlocal a # 找的是局部当中, 离他最近的上层的那个变量,也就是outer中的局部变量。 a = 300 # 修改的是离他最近的上层的那个变量, print(a) # 300 print(a) # 200, inner() # 调用内部函数, print(a) # 300,outer中的局部变量,在inner中被修改。outer()print(a) # 100 全部变量 """输出结果:200300300100""" a = 1def fun_1(): a = 2 def fun_2(): nonlocal a # 引入局部中离他最近的外层变量,及fun_1中的局部变量a a = 3 # 修改fun_1中的局部变量a的值为3 def fun_3(): a = 4 # fun_3中的局部变量,对其赋值不影响外部的变量 print('4---',a) # fun_1 中的局部变量a,值在fun_2中被修改为3, print('3---',a) # fun_1 中的局部变量a,值在fun_2中被修改为3, fun_3() # 此调用没有修外部的变量 print('5---',a) # fun_1 中的局部变量a,值在fun_2中被修改为3, print('2---',a) # fun_1 中的局部变量a,值为2 fun_2() # 此调用把fun_1 中的局部变量a,修改为3啦; print('6---',a) # fun_1 中的局部变量a,值在fun_2中被修改为3,print('1---',a) # 全局变量a,值为1fun_1()print('7---',a) # 全局变量a,值为1 """输出结果:1--- 12--- 23--- 34--- 45--- 36--- 37--- 1"""

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200802A0JXRB00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券