FIsh论坛《零基础入门学习Python》| 第018讲:函数:灵活即强大 | 课后测试题及答案
测试题:
0. 请问以下哪个是形参哪个是实参?
def MyFun(x):
return x ** 3
y = 3
print(MyFun(y))
输出结果:
27
形参:x,实参:y=3
形参指的是函数创建和定义过程中小括号里的参数,而实参指的是函数在调用过程中传递进去的参数。
1.函数写注释有什么不同?
给函数写文档是为了让别人可以更好的理解你的函数,所以这是一个好习惯。
def MyFirstFunction(name):
'函数文档在函数定义的最开头部分,用不记名字符串表示'
print('I love FishC.com!')
DocStrings 文档字符串是一个重要工具,用于解释文档程序,帮助你的程序文档更加简单易懂。
我们可以在函数体的第一行使用一对三个单引号 ‘’’ 或者一对三个双引号 “”" 来定义文档字符串。
你可以使用 doc(注意双下划线)调用函数中的文档字符串属性。
def function():
''' say something here!函数文档在函数定义的最开头部分,用不记名字符串表示
'''
pass
print(function.__doc__) # 调用 doc
help(function)
输出结果为:
say something here!函数文档在函数定义的最开头部分,用不记名字符串表示
Help on function function in module __main__:
function()
say something here!函数文档在函数定义的最开头部分,用不记名字符串表示
- 使用关键字参数,可以有效避免什么问题的出现呢?
关键字参数,是指函数在调用的时候,带上参数的名字去指定具体调用的是哪个参数,从而可以不用按照参数的顺序调用函数,例如:
关键字参数,是指函数在调用的时候,带上参数的名字去指定具体调用的是哪个参数,从而可以不用按照参数的顺序调用函数,例如:
def SaySome(name, words):
print(name + '->' + words)
SaySome(words='让编程改变世界!', name='小甲鱼')
- 使用help(print)查看print()这个BIF有哪些默认参数?分别起到什么作用?
help(print)
输出结果:
print(...)
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
谷歌翻译结果
打印(…)
打印(值,…,sep='',end='\n',file=sys.stdout,flush=False)
将值打印到流,默认情况下打印到sys.stdout。
可选关键字参数:
文件:类似文件的对象(流);默认为当前sys.stdout。
sep:在值之间插入的字符串,默认为空格。
结束:最后一个值后追加的字符串,默认为换行符。
冲洗:是否强制冲洗水流。
4. 默认参数和关键字参数表面最大的区别是什么?
呃,其实这道题考大家有没有认真听课啦~
**关键字参数**是在函数调用的时候,通过参数名制定需要赋值的参数,这样做就不怕因为搞不清参数的顺序而导致函数调用出错。而**默认参数**是在参数定义的过程中,为形参赋初值,当函数调用的时候,不传递实参,则默认使用形参的初始值代替。
关键字参数
# 以下是用关键字参数正确调用函数的实例
print_hello('tanggu', sex=1)
print_hello(1, name='tanggu')
print_hello(name='tanggu', sex=1)
print_hello(sex=1, name='tanggu')
# 以下是错误的调用方式
print_hello(name='tanggu', 1)
print_hello(sex=1, 'tanggu')
通过上面的代码,我们可以发现:有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序的
位置参数
调用函数时根据函数定义的参数位置来传递参数。
#!/usr/bin/env python
# coding=utf-8
def print_hello(name, sex):
sex_dict = {1: u'先生', 2: u'女士'}
print('hello %s %s, welcome to python world!' % (name, sex_dict.get(sex, u'女士')))
# 两个参数的顺序必须一一对应,且少一个参数都不可以
print_hello('tanggu', 1)
print_hello('tanggu',2)
输出结果:
hello tanggu 先生, welcome to python world!
hello tanggu 女士, welcome to python world!
默认参数
用于定义函数,为参数提供默认值,调用函数时可传可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)
# 正确的默认参数定义方式--> 位置参数在前,默认参数在后
def print_hello(name, sex=1):
....
# 错误的定义方式
def print_hello(sex=1, name):
....
# 调用时不传sex的值,则使用默认值1
print_hello('tanggu')
# 调用时传入sex的值,并指定为2
print_hello('tanggu', 2)
动动手:
- 编写一个符合以下要求的函数:
a) 计算打印所有参数的和乘以基数(base=3)的结果
b) 如果参数中最后一个参数为(base=5),则设定基数为5,基数不参与求和计算。
def mFun(*param, base=3):
result = 0
for each in param:
result += each
result *= base
print('结果是:', result)
mFun(1, 2, 3, 4, 5, base=5)
输出结果:
结果是: 75
- 寻找水仙花数
题目要求:如果一个3位数等于其各位数字的立方和,则称这个数为水仙花数。例如153 = 13+53+3^3,因此153是一个水仙花数。编写一个程序,找出所有的水仙花数。
方法一:
def Narcissus():
for each in range(100, 1000):
temp = each
sum = 0
while temp:
sum = sum + (temp % 10) ** 3
temp = temp // 10 # 注意这里用地板除
if sum == each:
print(each, end='\t')
print("所有的水仙花数分别是:", end='')
Narcissus()
输出结果:
所有的水仙花数分别是:153 370 371 407
方法二:
def Find():
for i in range(100, 1000):
if int(str(i)[0]) ** 3 + int(str(i)[1]) ** 3 + int(str(i)[2]) ** 3 == i:
print(i)
Find()
输出结果:
153
370
371
407
- 编写一个函数 findstr(),该函数统计一个长度为 2 的子字符串在另一个字符串中出现的次数。
例如:假定输入的字符串为“You cannot improve your past, but you can improve your future. Once time is wasted, life is wasted.”,子字符串为“im”,函数执行后打印“子字母串在目标字符串*出现 3 次”。
程序执行效果:
参考答案1:
def findStr(desStr, subStr):
count = 0
length = len(desStr)
if subStr not in desStr:
print('在目标字符串中未找到字符串!')
else:
for each1 in range(length - 1):
if desStr[each1] == subStr[0]:
if desStr[each1 + 1] == subStr[1]:
count += 1
print('子字符串在目标字符串*出现 %d 次' % count)
desStr = input('请输入目标字符串:')
subStr = input('请输入子字符串(两个字符):')
findStr(desStr, subStr))
输出结果:
请输入目标字符串:You cannot improve your past, but you can improve your future. Once time is wasted, life is wasted.
请输入子字符串(两个字符):im
子字符串在目标字符串*出现 3 次
参考答案2:
def findstr():
str1 = input('请输入目标字符串:')
str2 = input('请输入子字符串(两个字符):')
count = 0
for i in range(len(str1) - 1):
str3 = str1[i] + str1[i + 1]
if str3 == str2:
count += 1
print('子字符串在目标字符串*出现%s次' % count)
- 请写下这一节课你学习到的内容:格式不限,回忆并复述是加强记忆的好方式!
本节课主要针对函数的参数进行进一步学习。
(1)形参和实参
(2)函数文档
(3)关键字参数
用于函数调用,通过**“键-值”形式**加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求
(4)默认参数
(5)收集参数(可变参数)
可变参数
定义函数时,有时候我们不确定调用的时候会传递多少个参数(不传参也可以)。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递,会显得非常方便。
包裹位置传递
def func(*args):
....
# func()
# func(a)
# func(a, b, c)
我们传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是包裹位置传递。
包裹关键字传递
def func(**kargs):
....
# func(a=1)
# func(a=1, b=2, c=3)
kargs是一个字典(dict),收集所有关键字参数
小结:
位置参数:
调用函数时所传参数的位置必须与定义函数时参数的位置相同
关键字参数:
使用关键字参数会指定参数值赋给哪个形参,调用时所传参数的位置可以任意
位置参数:可接受任意数量的位置参数(元组);
只能作为最后一个位置参数出现,其后参数均为关键字参数
关键字参数:可接受任意数量的关键字参数(字典);只能作为最后一个参数出现
**默认参数:**默认参数的赋值只会在函数定义的时候绑定一次,默认值不会再被修改