[course]02 —— Python Functions
函数定义后是否执行?
空函数的定义方法 pass的使用
函数的返回值? 什么是函数的返回值
函数的返回值可以包含多个值
EX18
# this one is like your scripts with argv
def print_two(*args):
print(args)
*arg1, arg2 = args
print(f"arg1: {arg1}, arg2: {arg2} ")
# ok, that *args is actually pointless, we can just do this
def print_two_again(arg1, arg2="333"):
print(f"arg1: {arg1}, arg2: %{arg2}")
# this just takes one argument
def print_one(arg1):
print(f"arg1: {arg1}")
# this one takes no arguments
def print_none():
print("I got nothing.")
print_two("Zed", "Shaw")
print_two_again("Zed", "Shaw")
print_one("First!")
print_none()EX21
方法的参数,方法可以有多个参数,也可以不带参数
Builtin Functions
Module Functions
Variable Scope
外部不能访问在方法内部声明的变量
在方法内部定义的变量只能在方法内部使用,它的作用域仅存在于方法内部
在方法外定义的变量(global scope),可以在多个方法中共享
方法的返回值
基本返回值
方法return之后,方法直接退出,不会执行后续流程
方法如果没有return,默认会返回None
下面是作业中会用到的部分
方法组合
在方法内可以调用其他的方法,从而形成方法的组合
Helper Functions
作业中出现的方法,帮助使用的
测试方法
出现错误的用例
正确的用例版本
函数的扩充阅读和讲解
函数的定义
函数定义后是否执行?
空函数的定义方法 pass的使用
函数的返回值? 什么是函数的返回值
函数的返回值可以包含多个值
比如在游戏中经常需要从一个点移动到另一个点,给出坐标、位移和角度,就可以计算出新的新的坐标:
然后,我们就可以同时获得返回值:
但其实这只是一种假象,Python函数返回的仍然是单一值:
原来返回值是一个tuple!但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便。
函数的调用
函数的参数
默认参数
使用=定义默认参数
可变参数
关键字参数
可变参数
在Python函数中,还可以定义可变参数。顾名思义,可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。
我们以数学题为例子,给定一组数字a,b,c……,请计算a2 + b2 + c2 + ……。
要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,我们首先想到可以把a,b,c……作为一个list或tuple传进来,这样,函数可以定义如下:
但是调用的时候,需要先组装出一个list或tuple:
如果利用可变参数,调用函数的方式可以简化成这样:
所以,我们把函数的参数改为可变参数:
定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数:
如果已经有一个list或者tuple,要调用一个可变参数怎么办?可以这样做:
这种写法当然是可行的,问题是太繁琐,所以Python允许你在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去:
*nums表示把nums这个list的所有元素作为可变参数传进去。这种写法相当有用,而且很常见。
关键字参数
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。请看示例:
函数person除了必选参数name和age外,还接受关键字参数kw。在调用该函数时,可以只传入必选参数:
也可以传入任意个数的关键字参数:
关键字参数有什么用?它可以扩展函数的功能。比如,在person函数里,我们保证能接收到name和age这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。
和可变参数类似,也可以先组装出一个dict,然后,把该dict转换为关键字参数传进去:
当然,上面复杂的调用可以用简化的写法:
**extra表示把extra这个dict的所有key-value用关键字参数传入到函数的**kw参数,kw将获得一个dict,注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra。
命名关键字参数
对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。至于到底传入了哪些,就需要在函数内部通过kw检查。
仍以person()函数为例,我们希望检查是否有city和job参数:
但是调用者仍可以传入不受限制的关键字参数:
如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city和job作为关键字参数。这种方式定义的函数如下:
和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。
调用方式如下:
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:
命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错:
由于调用时缺少参数名city和job,Python解释器把这4个参数均视为位置参数,但person()函数仅接受2个位置参数。
命名关键字参数可以有缺省值,从而简化调用:
由于命名关键字参数city具有默认值,调用时,可不传入city参数:
使用命名关键字参数时,要特别注意,如果没有可变参数,就必须加一个*作为特殊分隔符。如果缺少*,Python解释器将无法识别位置参数和命名关键字参数:
参数组合
在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
比如定义一个函数,包含上述若干种参数:
在函数调用的时候,Python解释器自动按照参数位置和参数名把对应的参数传进去。
最神奇的是通过一个tuple和dict,你也可以调用上述函数:
所以,对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的。
虽然可以组合多达5种参数,但不要同时使用太多的组合,否则函数接口的可理解性很差。
Last updated
Was this helpful?