8.函数

本文中将讲解Python中函数的知识

一、实验目的

  • 函数的定义
  • 局部/全局变量的概念
  • 默认参数,关键字参数及强制关键字参数
  • 文档字符串的使用
  • 高阶函数,map() 函数

二、知识要点

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。函数能提高应用的模块性,和代码的重复利用率。我们已经知道Python提供了许多内建函数,比如print()。但我们也可以自己创建函数,这被叫做用户自定义函数。

1.定义一个函数
  • 流程:
    • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
    • 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
    • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
    • 函数内容以冒号起始,并且缩进。
    • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
  • 语法格式:
1
2
3
4
5
#定义  函数名  (参数):
def functionname( parameters ):
"函数_文档字符串"
function_suite
return [expression]
2.调用函数

定义一个函数只给了函数一个名称,指定了函数里包含的参数,和代码块结构。这个函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从Python提示符执行。

3.对象
对象类型
可更改对象 Strings(字符串) tuples(元组) numbers(数字
不可更改对象 list(列表) dict(字典)

下面的例子将解析可更改对象与不可更改对象的区别:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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.参数
  • 必备参数:必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。例如:
1
2
3
4
5
6
7
8
def must(str):
print(str)
return

try:
must()
except Exception:
print("未传入参数异常")

该代码会输出未传入参数异常

  • 关键字参数:关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。例如:
1
2
3
4
5
6
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,关键字参数顺序不重要。

  • 默认参数:调用函数时,默认参数的值如果没有传入,则被认为是默认值。例如:
1
2
3
4
5
6
def default(name, age=35):
print("name is {},age is {}".format(name, age))
return

default(name='zhang',age=50);
default(name='zhe')

输出为:

1
2
name is zhang,age is 50
name is zhe,age is 35

  • 不定长参数:处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述2种参数不同,声明时不会命名。基本语法如下:
1
2
3
4
def functionname([formal_args,] *var_args_tuple ):
"函数_文档字符串"
function_suite
return [expression]

加了星号(*)的变量名会存放所有未命名的变量参数。不定长参数实例如下:

1
2
3
4
5
6
7
8
9
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)

输出:
1
2
3
4
5
输入的常量是: 10
输入的常量是: 10
可变参数: 20
可变参数: 30
可变参数: 40

在可变参数后定义的参数必须通过关键词传入:
例如:

1
2
3
4
5
6
7
8
9
10
11
12
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("传入异常")

输出为:
1
2
传入异常
传入name为zhang,age为16

5.匿名函数

python 使用 lambda 来创建匿名函数。lambda只是一个表达式,函数体比def简单很多。lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
匿名函数语法:

1
lambda [arg1 [,arg2,.....argn]]:expression

例如:
1
2
3
4
5
sum = lambda arg1, arg2: arg1 + arg2

# 调用sum函数
print("相加后的值为 : ", sum(10, 20))
print("相加后的值为 : ", sum(20, 20))

输出为:
1
2
相加后的值为 :  30
相加后的值为 : 40

6.return语句

return语句[表达式]退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。之前的例子都没有示范如何返回数值,下例便告诉你怎么做:

1
2
3
4
5
6
7
8
9
def sum(arg1, arg2):
# 返回2个参数的和."
total = arg1 + arg2
print("函数内 : ", total)
return total


# 调用sum函数
total = sum(10, 20)

该程序输出函数内 : 30

7.全局变量与局部变量

定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。下面的例子有助于理解这两个概念:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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)

输出:
1
2
3
4
5
6
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__(注意双下划线)调用函数中的文档字符串属性。例如:

1
2
3
4
5
6
7
def function():
''' say something here!
'''
pass


print(function.__doc__) # 调用 doc

输出为say something here!

9.高阶函数

高阶函数(Higher-order function)或仿函数(functor)是可以接受函数作为参数的函数:

  • 使用一个或多个函数作为参数
  • 返回另一个函数作为输出

例如:

1
2
3
4
5
6
7
8
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.定义一个函数用于实现求和运算
  • 代码:
1
2
def sum_my(a, b):
return a + b
2.在代码中调用求和方法
  • 代码:
1
2
3
4
5
6
7
8
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))
  • 结果:
1
2
3
Please enter an number:2
Please enter another number:3
方法调用成功,传入的参数a=2,b=3,结果为: 5
3.重要的高阶函数

3.1 map()

map 是一个在 Python 里非常有用的高阶函数。它接受一个函数和一个序列(迭代器)作为输入,然后对序列(迭代器)的每一个值应用这个函数,返回一个序列(迭代器),其包含应用函数后的结果。举例:

1
2
3
4
5
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()

1
2
3
4
5
6
7
8
9
# 反向排序
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]]

输出:

1
2
['g', 'f', 'e', 'd', 'c', 'b', 'a']
[[1, 2], [8, 3], [5, 6], [2, 8], [3, 10]]

  • sorted是Python提供的功能强大的排序函数,满足字符、数字等排序要求;
  • 函数的第一个参数为可迭代对象,第二个参数key作为排序的规则(指定按什么排序),第三个参数表明是否反向;
  • sorted函数的返回结果是列表类型;

3.3 filter()

1
2
3
4
5
6
# 过滤
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
2
3
1
10
20

  • filter函数也是接收一个函数和一个序列的高阶函数,其主要功能是过滤;
  • 第一个参数是一个函数,第二个参数是可迭代对象;
  • filter函数的返回值是迭代器对象filter;

四、实验结果


下一篇:9.文件处理
上一篇:7.字符串
目 录:Python学习

本文标题:8.函数

文章作者:小哲

发布时间:2020年03月08日 - 21:41

最后更新:2020年03月30日 - 11:41

原始链接: 点击复制原始链接

许可协议: 协议-转载请保留原文链接及作者