函数:
函数是带名字的代码块,用于完成具体的工作。要执行函数定义的特定任务,可调用该函数。需要在程序中多次执行同一项任务时,
你无需反复编写完成该任务的代码,而只需调用执行该任务的函数,让Python运行其中的代码。
1、定义函数
(1)定义一个函数具有以下的规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号 : 起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。
下面是一个简单的使用案例:
-
def greet_user():
-
"""显示简单的问候语"""
-
print("Hello!")
-
greet_user()
(2)实参和形参
以下是一个测试用例:
-
def sum_num(a, b):
-
return a + b
-
print(sum_num(1, 2))
在上述程序中,变量a, b均为形参,是定义在sum_num中的局部变量,1和2是实参,实参是调用函数时传递给函数的信息。
当我们调用函数sum_num时,传递了1和2,相当于执行了a = 1, b = 2,此时a存储的值为1,b中存储的值为2。
2、传递实参
鉴于函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参。向函数传递实参的方式很多,可使用位置实参,
这要求实参的顺序与形参的顺序相同;也可使用关键字实参,其中每个实参都由变量名和值组成;还可使用列表和字典。
(1)位置实参
调用函数时,Python必须将函数调用中的每个实参都关联到函数定义中的一个形参。为此,最简单的关联方式是基于实参的顺序。这种关联方式被称为位置实参。
-
def sum_num(a, b):
-
print(a)
-
print(b)
-
return a + b
-
print(sum_num(1, 2))
在上述代码中,当我们在调用函数时,传入1和2,被调用函数会直接按照参数的顺序,将1赋给a,2赋给b。如果传入参数为2和1,则按照顺序,a中的值为2,b中的值为1。
(2)关键字实参
关键字实参是传递给函数的名称---值对。直接在实参中将名称和值关联起来了,因此向函数传递实参时不会混淆。
关键字实参让你无需考虑函数调用中的实参顺序,还清楚地指出了函数调用中各个值的用途。
-
def sum_num(a, b):
-
print(a)
-
print(b)
-
return a + b
-
print(sum_num(a=1, b=2))
-
print(sum_num(b=2, a=1))
在实参中,我们直接使a = 1, b = 2,不管顺序如何,现在已经将具体的值和形参关联了,所以可以得到相同的结果。
(3)默认值
编写函数时,可给每个形参指定默认值。在调用函数中给形参提供了实参时,Python将使用指定的实参值;否则,将使用形参的默认值。因此,
给形参指定默认值后,可在函数调用中省略相应的实参。使用默认值可简化函数调用,还可清楚地指出函数的典型用法。
注意使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的实参。这让Python依然能够正确地解读位置实参。
-
def sum_num(a, b=2):
-
print(a)
-
print(b)
-
return a + b
-
print(sum_num(1))
在上述代码中我们调用函数时,只传入了1,这时1会自动匹配没有默认值的1,然后b使用默认值2。
(4)不定长参数
你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述3 种参数不同,声明时不会命名。
-
def printinfo( arg1, *vartuple ):
-
"打印任何传入的参数"
-
print ("输出: ")
-
print (arg1)
-
print (vartuple)
-
# 调用printinfo 函数
-
printinfo( 70, 60, 50 )
如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。如下实例:
-
def printinfo( arg1, *vartuple ):
-
"打印任何传入的参数"
-
print ("输出: ")
-
print (arg1)
-
for var in vartuple:
-
print (var)
-
return
-
# 调用printinfo 函数
-
printinfo( 10 )
-
printinfo( 70, 60, 50 )
还有一种就是参数带两个星号 **,加了两个星号 ** 的参数会以字典的形式导入。
-
def printinfo( arg1, **vardict ):
-
"打印任何传入的参数"
-
print ("输出: ")
-
print (arg1)
-
print (vardict)
-
# 调用printinfo 函数
-
printinfo(1, a=2,b=3)
(5)传递可变对象和不可变对象
在 python 中,类型属于对象,变量是没有类型的:
-
a=[1,2,3]
-
a="Runoob"
上代码中,[1,2,3] 是 List 类型,"Runoob" 是 String 类型,而变量 a 是没有类型,她仅仅是一个对象的引用(一个指针),可以是指向 List 类型对象,也可以是指向 String 类型对象。
可更改(mutable)与不可更改(immutable)对象
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
-
不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变 a 的值,相当于新生成了 a。
-
可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
-
不可变类型:类似 C++ 的值传递,如 整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a))内部修改 a 的值,则是新生成来一个 a。
-
可变类型:类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响
python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
3、返回值
函数并非总是直接显示输出,相反,它可以处理一些数据, 并返回一个或一组值。 函数返回的值被称为返回值。在函数中,可使用return语句将值返回到调用函数的代码行。
返回值让你能够将程序的大部分繁重工作移到函数中去完成,从而简化主程序。
(1)返回简单值
-
def sum_num(a, b):
-
return a + b
-
print(sum_num(1, 2))
(2)返回字典和列表
函数可返回任何类型的值,包括列表和字典等较复杂的数据结构
-
def sum_num(a, b):
-
ls = [a, b]
-
return ls
-
print(sum_num(1, 2))
4、匿名函数
python 使用 lambda 来创建匿名函数。
所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
- lambda 只是一个表达式,函数体比 def 简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
-
sum = lambda arg1, arg2: arg1 + arg2
-
# 调用sum函数
-
print ("相加后的值为 : ", sum( 10, 20 ))
-
print ("相加后的值为 : ", sum( 20, 20 ))