一、实验目的
- 函数的定义
- 局部/全局变量的概念
- 默认参数,关键字参数及强制关键字参数
- 文档字符串的使用
- 高阶函数,map() 函数
二、知识要点
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。函数能提高应用的模块性,和代码的重复利用率。我们已经知道Python提供了许多内建函数,比如print()。但我们也可以自己创建函数,这被叫做用户自定义函数。
1.定义一个函数
-
流程:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
- 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
-
语法格式:
#定义 函数名 (参数):
def functionname( parameters ):
"函数_文档字符串"
function_suite
return [expression]
2.调用函数
定义一个函数只给了函数一个名称,指定了函数里包含的参数,和代码块结构。这个函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从Python提示符执行。
3.对象
对象类型 | |||
---|---|---|---|
**可更改对象 ** | Strings(字符串) | tuples(元组) | numbers(数字 |
不可更改对象 | list(列表) | dict(字典) |
下面的例子将解析可更改对象与不可更改对象的区别:
def change(string_2, tuples_2, int_2, float_2, list_2, dict_2, set_2):
print("已收到传入参数,传入值为:", string_2, tuples_2, int_2, float_2, list_2, dict_2, set_2)
string_2 = "newstring"
del tuples_2
int_2 = 3
float_2 = 2.0
list_2[0] = "newlist1"
dict_2['dict1'] = "newfirst"
del set_2
print("已修改传入参数,目前的属性值为:", string_2, int_2, float_2, list_2, dict_2)
try:
print(tuples_2)
except Exception:
print("tumples_2已删除")
try:
print(set_2)
except Exception:
print("set_2已删除")
return
string_1 = "string" # 字符串对象
tuples_1 = ("tuples1", "tuples2", 3) # 元组对象
int_1 = 2 # 整型对象
float_1 = 1.0 # 浮点型对象
list_1 = ["list1", "list2", 3] # 列表对象
dict_1 = {"dict1": "first", "dict2": 2} # 字典对象
set_1 = {"set1", "set2", 3} # 集合对象
change(string_1, tuples_1, int_1, float_1, list_1, dict_1, set_1)
print("返回值为:\n", string_1, tuples_1, int_1, float_1, list_1, dict_1, set_1)
我们用一个表格来解析一下整个过程:
变量 | 输入 | 传入函数 | 修改之后 | 输出 |
---|---|---|---|---|
string | "string" | "string" | "newstring" | "string" |
tuples | ("tuples1","tuples2") | ("tuples1","tuples2") | delete | ('tuples1', 'tuples2', 3) |
int | 2 | 2 | 3 | 2 |
float | 1.0 | 1.0 | 2.0 | 1.0 |
list | ["list1", "list2", 3] | ["list1", "list2", 3] | ['newlist1', 'list2', 3] | ['newlist1', 'list2', 3] |
dict | {"dict1": "first", "dict2": 2} | {"dict1": "first", "dict2": 2} | {'dict1': 'newfirst', 'dict2': 2} | {'dict1': 'newfirst', 'dict2': 2} |
set | {"set1", "set2", 3} | {"set1", "set2", 3} | delete | {3, 'set1', 'set2'} |
可以看到,只有属性为列表对象list
,字典对象dict
可以在函数中修改,而字符串对象string
,整型对象int
,浮点型对象float
,元组对象tuples
,集合对象set
是无法在函数中修改的。
4.参数
- 必备参数:必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。例如:
def must(str):
print(str)
return
try:
must()
except Exception:
print("未传入参数异常")
该代码会输出未传入参数异常
。
- 关键字参数:关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。例如:
def keyword_1(name_1, age_1):
print("name_1 is {},age_1 is {}".format(name_1, age_1))
return
keyword_1(age_1=10, name_1="zhe")
该代码会输出name_1 is zhe,age_1 is 10
,关键字参数顺序不重要。
- 默认参数:调用函数时,默认参数的值如果没有传入,则被认为是默认值。例如:
def default(name, age=35):
print("name is {},age is {}".format(name, age))
return
default(name='zhang',age=50);
default(name='zhe')
输出为:
name is zhang,age is 50
name is zhe,age is 35
- 不定长参数:处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述2种参数不同,声明时不会命名。基本语法如下:
def functionname([formal_args,] *var_args_tuple ):
"函数_文档字符串"
function_suite
return [expression]
加了星号(*)的变量名会存放所有未命名的变量参数。不定长参数实例如下:
def nolenth_n(num_1, *num):
print("输入的常量是:", num_1)
for x in num:
print("可变参数:", x)
return
nolenth_n(10)
nolenth_n(10, 20, 30, 40)
输出:
输入的常量是: 10
输入的常量是: 10
可变参数: 20
可变参数: 30
可变参数: 40
在可变参数后定义的参数必须通过关键词传入:
例如:
def Force_key(name, *home, age):
print("传入name为{},age为{}".format(name, age))
return
try:
Force_key(name="zhang")
except Exception:
print("传入异常")
try:
Force_key("zhang",age=16)
except Exception:
print("传入异常")
输出为:
传入异常
传入name为zhang,age为16
5.匿名函数
python 使用 lambda 来创建匿名函数。lambda只是一个表达式,函数体比def简单很多。lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
匿名函数语法:
lambda [arg1 [,arg2,.....argn]]:expression
例如:
sum = lambda arg1, arg2: arg1 + arg2
# 调用sum函数
print("相加后的值为 : ", sum(10, 20))
print("相加后的值为 : ", sum(20, 20))
输出为:
相加后的值为 : 30
相加后的值为 : 40
6.return
语句
return语句[表达式]退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。之前的例子都没有示范如何返回数值,下例便告诉你怎么做:
def sum(arg1, arg2):
# 返回2个参数的和."
total = arg1 + arg2
print("函数内 : ", total)
return total
# 调用sum函数
total = sum(10, 20)
该程序输出函数内 : 30
7.全局变量与局部变量
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。下面的例子有助于理解这两个概念:
a = 9
def global_1():
try:
print(a)
a = 100
except Exception:
print("变量a误作局部变量")
def global_2():
try:
global a
print(a)
a = 100
except Exception:
print("变量a误作局部变量")
print("Before the function call ", a)
print("inside change function")
global_1()
print("After the function global_1() call ", a)
global_2()
print("After the function global_2() call ", a)
输出:
Before the function call 9
inside change function
变量a误作局部变量
After the function global_1() call 9
9
After the function global_2() call 100
当函数中只要用到了变量 a
,并且 a
出现在表达式等于号的前面,就会被当作局部变量。当执行到 print(a)
的时候会报错,因为 a
作为函数局部变量是在print(a)
之后才定义的。而当使用 global
关键字,对函数中的 a
标志为全局变量,让函数内部使用全局变量的a
,程序中就没有问题了。
8.文档字符串
DocStrings 文档字符串是一个重要工具,用于解释文档程序,帮助你的程序文档更加简单易懂。我们可以在函数体的第一行使用一对三个单引号'''
或者一对三个双引号"""
来定义文档字符串。你可以使用 __doc__
(注意双下划线)调用函数中的文档字符串属性。例如:
def function():
''' say something here!
'''
pass
print(function.__doc__) # 调用 doc
输出为say something here!
9.高阶函数
高阶函数(Higher-order function)或仿函数(functor)是可以接受函数作为参数的函数:
- 使用一个或多个函数作为参数
- 返回另一个函数作为输出
例如:
def high(l):
return [i.upper() for i in l]
# 创建高阶函数,接受一个函数和一个列表作为参数
def test(h, l):
return h(l)
l = ['python', 'Linux', 'Git']
print(test(high, l))
输出为['PYTHON', 'LINUX', 'GIT']
三、实验内容
1.定义一个函数用于实现求和运算
- 代码:
def sum_my(a, b):
return a + b
2.在代码中调用求和方法
- 代码:
def sum_my(a, b):
print("方法调用成功,传入的参数a=%d,b=%d,结果为:" % (a, b), end=" ")
return a + b
m = int(input("Please enter an number:"))
n = int(input("Please enter another number:"))
print(sum_my(m, n))
- 结果:
Please enter an number:2
Please enter another number:3
方法调用成功,传入的参数a=2,b=3,结果为: 5
3.重要的高阶函数
3.1 map()
map
是一个在 Python 里非常有用的高阶函数。它接受一个函数和一个序列(迭代器)作为输入,然后对序列(迭代器)的每一个值应用这个函数,返回一个序列(迭代器),其包含应用函数后的结果。举例:
lst = [1, 2, 3, 4, 5]
def square(num):
return num * num
print(list(map(square, lst)))
输出为[1, 4, 9, 16, 25]
- map函数用来将序列中的值处理再依次返回至列表内;
- 第一个参数func为函数,实现函数映射的功能,第二个参数为可迭代对象;
- map函数的返回值为一个迭代器对象map;
3.2 sorted()
# 反向排序
str = sorted('abcdefg', reverse=True)
print(str) # ['g', 'f', 'e', 'd', 'c', 'b', 'a']
# 按指定元素进行排序
obj = [[1,2], [5,6], [2,8], [8,3], [3,10]]
func = lambda x: x[1]
new_list = sorted(obj, key=func, reverse=False)
print(new_list) # [[1, 2], [8, 3], [5, 6], [2, 8], [3, 10]]
输出:
['g', 'f', 'e', 'd', 'c', 'b', 'a']
[[1, 2], [8, 3], [5, 6], [2, 8], [3, 10]]
- sorted是Python提供的功能强大的排序函数,满足字符、数字等排序要求;
- 函数的第一个参数为可迭代对象,第二个参数key作为排序的规则(指定按什么排序),第三个参数表明是否反向;
- sorted函数的返回结果是列表类型;
3.3 filter()
# 过滤
obj = filter(lambda x: x > 0, [-20, -10, -1, 0, 1, 10, 20])
print(obj) # <filter object at 0x004C9EB0>
for i in obj:
print(i) # 1 10 20
输出:
1
10
20
- filter函数也是接收一个函数和一个序列的高阶函数,其主要功能是过滤;
- 第一个参数是一个函数,第二个参数是可迭代对象;
- filter函数的返回值是迭代器对象filter;
四、实验结果
无
网友评论