目录
零、定义函数
最简单的函数
我们先来写一个打印固定语的函数,比如打印 “Hello World!”
def hello():
print("Hello World!")
hello()
结果:
def 告诉 python 要定义一个函数。函数名为 hello() ,它不需要任何信息就能完成工作,因此括号内是空的。
紧跟在第一行之后的缩进内容都是函数体,print("Hello World!") 就是函数的内容或者说函数的作用。
最后一行 hello() 即函数的调用。可以看到调用函数后打印了 Hello World!
向函数传递信息
对上面的函数稍加修改,比如我们在函数的括号中添加信息,比如添加 username,可以让函数接受任何你给 username 指定的值。
def hello(username):
print(f"Hello,{username.title()}!")
hello('lisa')
结果:
因为在定义函数时在括号中加入了信息,所以在调用时必须也要加上信息,否则会报错
形参与实参
在上一个函数的定义中,变量 username 是一个形参,即函数完成工作所需要的信息。而在调用函数时,值 ‘lisa’ 是一个实参,即调用函数时传递给函数的信息。
调用函数时,将要让函数使用的信息放在圆括号内。在 hello('lisa') 中,将实参 ‘lisa’ 传给函数 hello(username) 并被赋给了形参 username
壹、传递实参
位置实参
调用函数时,必须将函数调用中的每个实参都关联到函数定义中的一个形参。位置实参就是根据实参顺序进行关联的。
来简单看一个例子。
def full_name(first_name,last_name):
print(f"my first name is {first_name}")
print(f"my last name is {last_name}")
full_name('jim','vegetable')
结果:
这个函数定义了两个形参,调用函数时,需要按顺序提供 first_name 和 last_name
实参 'jim' 被赋给了形参 'first_name',实参 'vegetable' 被赋给了形参 'last_name'
关键字实参
关键字实参是传递给函数的名称值对。因为直接在实参中将名称和值关联起来,所以向函数传递参数时不会混淆。
所以无需考虑顺序,如下例
def full_name(first_name,last_name):
print(f"my first name is {first_name}")
print(f"my last name is {last_name}")
full_name(last_name = 'vegetable',first_name = 'jim')
结果:
函数和刚才的一样,但是在调用时明确的指出了各个实参对应的形参。因为 python 知道各个值该赋给哪个形参,所以实参的顺序就无关紧要了。
默认值
编写函数时,可以给每一个形参都指定一个默认值。调用函数时,如果提供了实参就用提供的值;如果未提供,则使用指定的默认值。
比如,我们默认 last_name 为 vegetable
def full_name(first_name,last_name = 'vegetable'):
print(f"\nmy first name is {first_name}")
print(f"my last name is {last_name}")
full_name('jim','vegetable')
full_name('jim')
full_name('jim','lee')
结果:
我第一次调用函数时,传入的实参是 ('jim','vegetable'),结果如第 1,2 行所示
第二次调用函数,只传入了一个参数,jim,但因为 last_name 有默认值,所以结果如第 3,4 行所示
第三次调用函数,传入的实参是 ('jim','lee'),指定了 last_name 的值,所以结果如第 5,6 行所示
传递任意数量的实参
有的时候,我们并不知道函数需要接受多少个实参,但是 python 允许函数从调用语句中收集任意数量的实参
def no_pass_stu(*stus):
print("\nno pass students' list:")
for stu in stus:
print(f"-{stu}")
no_pass_stu('lisa','jerry','tom','mark')
no_pass_stu('lisa','jerry')
结果:
*stus 让 python 生成一个名为 stus 的空元组,并将所有值都封装到这个空元组中。
结合使用位置实参和关键字实参
你可能会有疑惑,二者结合有什么用呢?其实用处可大了,比如说我们需要给不及格名单前加班级
def no_pass_stu(cla,*stus):
print(f"\nlist of no-pass students in {cla}:")
for stu in stus:
print(f"-{stu}")
no_pass_stu('193','lisa','jerry','tom','mark')
no_pass_stu('194','black','tony')
结果:
python 将收到的第一个值赋给 cla,并将其他所有值都存储在元组 stus 中,在函数调用中,首先指定班级,再根据需要指定学生
贰、返回值
返回简单值
函数不是只能直接显示输出,它还能处理一些数据,并返回一个或一组值。返回的这个值称为返回值。
def full_name(first_name,last_name):
fullname = f"{first_name} {last_name}"
return(fullname.title())
fullname = full_name('jim','vegetable')
print(fullname)
结果:
return(fullname.title()) 表示这个函数最终会返回 fullname.title() 的值
调用函数时,将返回值赋值给 fullname,然后在打印出来。
返回字典与列表
函数可返回任和类型的值,包括列表、字典等复杂的数据结构
返回字典
def full_name(first_name,last_name):
stu = {'first':first_name,'last':last_name}
return stu
stu = full_name('jim','vegetable')
print(stu)
结果:
返回列表
def full_name(first_name,last_name):
stu = [first_name,last_name]
return stu
stu = full_name('jim','vegetable')
print(stu)
结果:
传递列表
向函数传递列表十分有用,列表中包含的可能是名字、数或更复杂的对象。将列表传递给函数后,函数就能直接访问其内容。
def hello(user):
for user in users:
message = f"hell,{user.title()}!"
print(message)
users = ['lisa','jerry','vegetable']
hello(users)
结果:
hello(user) 函数收到列表后,遍历列表中的用户,并为每一个用户打印了一条问候语
叁、将函数存储在模块中
使用函数的有点就是可以将代码块与主函数分离。通过给函数指定描述性名称,能让代码更容易被理解。
还可以将函数储存在称为模块的独立文件中,再将模块导入到主程序中。
导入整个模块
要先导入就得先创建。模块是扩展名为 .py 的文件,其中包含着代码。
比如将以下代码作为模块保存在文件中,命名为 no_pass
并在此目录下新建一个 test 文件
在 test.py 文件中导入刚创建的模块 no_pass ,在调用这个函数
导入特定的函数
对于刚才的例子,如果只想导入要使用的函数,可以这样写
如此使用时,不用再指明文件名,只需使用函数即可
并且还可以使用 as 给函数取别名
同样的,还可以给模块指定别名,也是用 as
肆、小结
今天的任务差一点没有完成,越往后越难,或许真的有一天我没有完成当天的内容,但慢慢的会发现一个道理,什么东西它的结果固然重要,但真正能让你感到乐趣的是这个过程,这个过程或许困扰你了很久很久,当你有一天突然想明白的时候,那种喜悦是无可替代的。所以,过程困扰着你,不要悲伤,不要心急,忧郁的日子里需要镇静 。