总结: 当一个函数/过程没有使用 return 显示的定义返回值时,python 解释器会隐式的返回 None,所以在 python 中即便是过程也可以算作函数。
5. 函数返回值: def test01(): pass def test02(): return 0 def test03(): return 0,10,'hello',['gabriel','zzz'],{'celestial':'sky'} t1 = test01() t2 = test02() t3 = test03() print('from test01 return is [%s]:' %type(t1),t1) print('from test02 return is [%s]:' %type(t2),t2) print('from test03 return is [%s]:' %type(t3),t3) ---> from test01 return is [<class 'NoneType'>]: None from test02 return is [<class 'int'>]: 0 from test03 return is [<class 'tuple'>]: (0, 10, 'hello', ['gabriel', 'zzz'], {'celestial': 'sky'})
001 >> def test1(): print('in the test1') return 0 print('test finished') # 前一步return 0 结束函数,终止运行,所以这一步不会执行了 test1() # return 命令执行的函数时,结束函数,同时返回 0 # return 0 如何接收到? # 可以赋给一个变量,x代表接收函数体中的定义的return这个返回值的结果,赋值给x x = test1() print(x) ---> in the test1 in the test1 0
002 >> def test1(): print('in the test1') def test2(): print('in the test2') return 0 def test3(): print('in the test3') return 1,'hello',['aether','arthur'],{'name':'aether'} x=test1() y=test2() z=test3() print(x) print(y) print(z) ---> in the test1 ---> in the test2 ---> in the test3 ---> None ---> 0 ---> (1, 'hello', ['aether', 'arthur'], {'name': 'aether'}) # 返回的其实也是一个值,好比超市买东西,装到朔料袋中,装成一个东西 总结: 返回值数=0:返回None 返回值数=1:返回object 返回值数>1:返回tuple 为什么要有返回值?作用是什么? 最重要的作用是想要函数整个执行的结果,程序后面的逻辑需要根据这个返回值进行操作。
003 >> def test1(): print('in the test1') def test2(): print('in the test2') return 0 def test3(): print('in the test3') return test2 # 这个叫做高阶函数
004 >> 调用方法: 1. test()执行,()表示调用函数test,()内可以有参数也可没有 参数: 1.形参和实参 形参: 形式参数,不是实际存在,是虚拟变量。 在定义函数和函数体的时候使用形参,目的是在函数调用时接收实参(实参个数,类型应与实参一一对应) 实参: 实际参数,调用函数时传给函数的参数,可以是常量,变量,表达式,函数,传给形参 区别: 形参是虚拟的,不占用内存空间,形参变量只有在被调用时才分配内存单元 实参是一个变量,占用内存空间,数据传送单向,实参传给形参,不能形参传给实参 2.位置参数和关键字 (标准调用:实参与形参位置一一对应;关键字调用:位置无需固定) 3.默认参数 4.参数组
004-1 现在变成有参数的函数 def test(x,y): print(x) print(y) test(1,2) # x 和 y 为位置参数,形参和实参位置是一一对应的,个数不能超,少了也不行 # 1传给了x,2传给了y, x y 为形参,1和2是实参,如果不调用这个函数,x和y 永远不会占用空间。 # x=1 1是真实存在于内存中的变量,而 x 只是一个引用的内存地址;1 代表门,x 代表门牌号,只是屋子空间的一个标识而已。
004-2 现在换一种方式 def test(x,y): print(x) print(y) test(y=1,x=2) ---> 2 ---> 1 # 位置参数调用,与形参一一对应
004-3 def test(x,y): print(x) print(y) x=1 # 定义一个内存对象,x来引用 y=2 test(y=y,x=x) # 前面的y是 test中代表的形参,后面的y是实际的值,道理一样的 ---> 1 ---> 2 # 不管形参的定义顺序,形参叫什么名字,就赋什么值 # 关键字调用,与形参顺序无关 # 以上是关键字调用和位置参数的调用
004-4 如果只有一个是形参调用 def test(x,y): print(x) print(y) test(x=2,3) ---> SyntaxError: positional argument follows keyword argument # 这样执行是不行的
004-5 如果只有一个是形参调用 def test(x,y): print(x) print(y) test(3,y=2) ---> 3 ---> 2 # 3给x y=2给 y
004-6 def test(x,y): print(x) print(y) test(3,x=2) ---> Exception has occurred: TypeError ---> test() got multiple values for argument 'x' ---> File "F:\Visual Studio Code\OLDBOTPYFILE_TRIAL\TRIAL.py", line 4, in <module> ---> test(3,x=2) # 这种不是位置调用,也不是关键字调用,混一起了,就会报错 # 如果既有关键字调用,又有位置参数调用,按照位置来 # 左边写一个值,是位置调用,右边就一定会传给y,其他的一定是错的,y=2可以,是因为满足了位置关系
004-7-1 如果是三个参数呢? # 关键参数是不能写在位置参数前面的 def test(x,y,z): print(x) print(y) print(z) test(3,y=2,6) ---> SyntaxError: positional argument follows keyword argument # 错误,因为关键参数是不能写在位置参数前面的
004-7-2 def test(x,y,z): print(x) print(y) print(z) test(3,z=2,y=6) ---> 3 ---> 6 ---> 2 # 如果后面是关键参数,这样就是可以的,一定不能放位置参数前面
3. 默认参数 3-1-1 def test(x,y=2): print(x) print(y) # 在写形参的时候,提前赋值,等于 2 了 test(1) ---> 1 2 没有赋值给y,因为 y 是默认等于 2 3-1-2 可以赋值吗? def test(x,y=2): print(x) print(y) test(1,y=3) # 关键字调用 ---> 1 3 3-1-3 def test(x,y=2): print(x) print(y) test(1,3) # 位置调用 ---> 1 3 # 默认参数特点:调用函数的时候,默认参数非必须传递 # 用途: # 1. 默认安装值 比如,安装软件,默认一键安装,和自定义安装的区别 # 2. 比如连接数据库端口号 3-1-4 1. 默认安装值 def test(x,soft1=True,soft2=True): print(x) 2. 比如连接数据库端口号 def conn(host,port=3306): pass
4. 参数组 def test(): pass # 前面提到的,位置参数,关键字参数,默认参数;参数定义好后,都有一个特点,调用个数超过形参,就报错,少了也不行 # 默认参数在参数调用时,可有可无 需求:实参数目不固定,形参应该如何定义? 参数组的定义:*args (变量名随意) 方式1 def test(*args): print(args) test(1,2,3,4,5,5) # 形参以 *开头,定义一个变量名 方式2 def test(*args): print(args) test(*[1,2,4,5,5]) # *args = *[1,2,3,4,5] 会变成元组 -→ args = tuple([1,2,3,4,5]) # *代表一个功能,是一个功能代号
4-1 将* 和位置参数结合起来 def test1(x,*args): print(x) print(args) test1(1,2,3,4,5,6,7) ---> 1 (2,3,4,5,6,7) 应用:函数在定义时,业务发展一段时间后,参数可能会不够,这样只能改源代码,为了避免不多传一个参数就改源代码就会用到了,以后会经常用到 元组就是 只读列表
4-2 可以传字典吗? def test2(**kwargs): print(kwargs) test2(name='gabriel',age=8,sex = '?') # name相当于 key gabriel 相当于 value;可以无限向下传 # 会将 三个 关键字参数传给 kwargs ---> {'name': 'gabriel', 'age': 8, 'sex': '?'} # 这就是把关键字转换成字典的方式 存放起来 # **kwargs: 把关键字参数,转换成字典的方式
4-2-1 可以跟位置参数吗? def test2(**kwargs): print(kwargs) print(kwargs['name']) print(kwargs['age']) test2(**{'name':'gabriel','age':8}) ---> {'name': 'gabriel', 'age': 8} gabriel 8
4-2-2 可以跟位置参数吗? def test3(name,**kwargs): print(name) print(kwargs) test3('gabriel') ---> gabriel {} # name 必须指定一个值,kwargs 需要指定一个吗?
4-2-2-1 def test3(name, **kwargs): print(name) print(kwargs) test3('gabriel','xxx') # 'xxx' 是位置参数,不是关键字参数,所以会报错,相当于给 name 赋值两个 # 所以,应该用 关键字的方式去写 4-2-2-2 def test3(name,**kwargs): print(name) print(kwargs) test3('gabriel',age=18000,sex='N') ---> gabriel {'age': 18000, 'sex': 'N'} # 这是和位置参数结合 4-2-3 如果和默认参数加一起 参数组有两种方式 *args 接收多个参数,转成元组的形式 **kwargs 把关键字参数,转换成字典的方式 # 可以把默认参数写在后面吗?不可以!!一定要放前面! 参数组一定要往后放!! def test4(name,age=10000,**kwargs): print(name) print(age) print(kwargs) test4('celestial',sex='N',hobby='sleep') ---> celestial 10000 {'sex': 'N', 'hobby': 'sleep'} 4-2-3-1 def test4(name,age=9999,**kwargs): print(name) print(age) print(kwargs) test4('gabriel',sex='N',hobby='fly',age=99999999) ---> gabriel 99999999 {'sex': 'N', 'hobby': 'fly'} # 结果同样可行,给默认参数赋值时,默认参数可以不赋值,可以以位置参数的方式赋值,也可以关键字赋值对应 4-2-3-2 def test4(name,age=0,**kwargs): print(name) print(age) print(kwargs) test4('gabriel',99999,sex='N',hobby='sleep',age=10000) ---> Traceback (most recent call last): File "f:/Visual Studio Code/PyFiles/MML/Management_Project_2/blank_module_name/tobp_2.py", line 5, in <module> test4('gabriel',99999,sex='N',hobby='sleep',age=10000) TypeError: test4() got multiple values for argument 'age' # 多个值给 age了,给默认参数赋值,两种方式,位置参数已经对应了,关键字参数又给对应了一遍,所以报错了
4-3 如果全部放在一起弄呢? def test4(name,age=0,*args,**kwargs): print(name) print(age) print(args) print(kwargs) test4('gabriel',age=10000,sex='N',hobby='sleep') ---> gabriel 10000 () {'sex': 'N', 'hobby': 'sleep'} # *args 接收的是位置参数,不能接收关键字参数 # *args 接收 N 个位置参数,转换成元组的形式 这里的 *args 无法接收位置参数,所以直接变为 空 sex='N',hobby='sleep' 给 kwargs 了,所以是生成字典 位置参数,不能写关键字参数后面
查看更多关于20201112 函数式编程之参数详解的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did162457