最强 Python3 基础
什么是函数?函数是一段可以被另一段程序可以重复利用的代码,也就是说这些代码在某些情况下是通用的,那通用的就代表函数里面的输入和输出格式都是差不多的。
在这之前,我们已经用过许多系统内的函数了,如每次都用的 print()
函数,和列表的内置函数 append()
,insert()
等,这些是系统内置的函数,里面的代码细节我们都是不需要管的,只需要知道怎么使用就行。那现在问题来了,如果我们想自己创建一段可重复使用的函数,那如何来创建呢?
介绍
下面先看一下函数的基本格式,Python 中因为对代码格式有着严格的要求,只要有一点格式错误都不能运行,所以我们在平常编写过程中一定要注意文本编辑器给我们的警告,及时修正格式。
可以从上面这张图看到,函数的定义其实可以分为五部分:def
关键词、函数名、参数、函数体以及 return
关键词返回的内容。可以用下面的例子来简化图中的内容。注意:函数中每个不同的部分之前一定要用四个空格来缩进一部分,可以看下面例子,例子中函数体的前面特意空了四个空格,用来区分这部分开始就是函数体。
def 函数名(参数列表):
函数体
如果不用四个空格区分会有什么结果?Python 不像 Java 一样是有着明确的代码范围的,如 Java 中使用大括号来将函数体括起来,而 Python 中因为倡导的是简单,所以将这种明确函数范围的大括号都去掉了,所以导致如果不用空格明确区分开函数体的话,那就无法识别了。可以看下面的 Java 和 Python 的函数例子的区别。
# Java版函数
public int sum(int x, int y) {
if (x > y) {
return x + y;
} else {
return x;
}
}
# =====================================================================
# Java 版不规范代码
public int sum(int x, int y) {
if (x > y) {
return x + y;
} else {
return x;
}
}
# =====================================================================
# Python 版函数
def sum(x, y):
if x > y:
return x + y
else :
return x
可以看到上面的例子中 Java 版函数明显比 Python 多了许多的大括号和中括号,我们不用理解 Java 中 public
的意思,只需要看格式就行。在 Python 中,因为没有特别的函数边界,所以只能使用四个空格来划分每部分的边界,而 Java 因为使用大括号和小括号来规范了边界,所以就算在第二个例子中不规范写代码其实也不会报错,最多就是识别的成本较高而已。而 Python 如果不规范写代码,则会直接报错,提醒我们一定要各个部分前面加空格。
下面看两个实际的使用例子。下面的例子中定义了两个函数,每个函数都各自返回了字符串,然后再外部调用函数的时候将这两个结果给拼接起来了,所以最后的输出结果就是两个字符串拼接的结果。
def hello():
return 'Hello World! '
def python():
return 'Python'
print(hello() + python())
# 输出 >>>
Hello World! Python
这边例子中的函数只定义了一个打印字符串的函数体,在下面调用函数的时候就会把这串字符串给打印出来。
def myPrint():
print('Hello World!')
myPrint()
# 输出 >>>
Hello World!
一、参数
函数的参数有四种类型:必需参数、关键字参数、默认参数和不定长参数。
参数名称 | 格式 | 解释 |
---|---|---|
必需参数 | def func(param1, param2) | 必需参数必须用正确的顺序传入。 |
关键字参数 | def func(pa=param1, param2) | 可以根据参数名来匹配参数,不用按顺序传入 |
默认参数 | def func(param1, param2=123) | 如果没有给参数,可以指定一个默认值的参数 |
不定长参数 | def func(param1, *param2) | 如果实际传入的参数的数量和预计传入的参数的数量无法匹配,则可以使用不定长参数 |
1. 必需参数
必须参数就是一定要传入的参数,还必须以正确顺序传入,如果不传入或者不以正确顺序,都会导致函数不能正常使用。可以看下面的几个例子。
下面的例子是参数都是以正确顺序传入,所以最后能正确输出结果。
def func(param1, param2):
print(param1, '-', param2)
func('str', 123)
# 输出 >>>
str - 123
而再下面的两个例子,一个缺少参数(Python 会报错),一个不以正确的顺序传入(和实际所想的结果有出入)。两个例子都无法正确完成函数所需要执行的过程。缺少参数的函数在执行的时候,控制台就输出对应的参数缺少的错误。而第二个例子中,因为参数传入的顺序不是按照规定的传入,导致输出的结果和我们所想的有出入。
# 缺少参数
def func(param1, param2):
print(param1, '-', param2)
func('str')
# 输出 >>>
TypeError: func() missing 1 required positional argument: 'param2'
# ===========================================================================================
# 参数传入顺序不正确
def func2(str, num):
print('字符串参数:', str)
print('数字参数:', num)
func2(123, 'Python')
# 输出 >>>
字符串参数: 123
数字参数: Python
2. 关键字参数
关键词参数的传入和 format 格式化的参数传入是一样的,都是以键值对的形式传入,用来指定某个值对应到具体的键上,然后在函数中会根据键来获取相对应的值。在某些参数比较多的情况下,这种关键词参数能很快的辨识出来我们想要的参数。
同时,关键字参数还能不用像必需参数根据既定的顺序来传入参数,也就是只要指定的键值对是正确的,那在传入的时候,顺序不同,也不会影响输出。
我们还是用一个例子来展示关键字参数,并以不同于函数指定的参数顺序来传入参数。可以看到例子中的输出结果是符合我们内心中所想的。
def func(str, num):
print('字符串参数:', str)
print('数字参数:', num)
func(num = 123, str = 'Python')
# 输出 >>>
字符串参数: Python
数字参数: 123
如果一开始就是以关键字参数传入参数,那之后所有的参数指定都只能以关键字的形式来传入,不能再用必需参数的形式传入,因为这会导致歧义。
def func(str, num):
print('字符串参数:', str)
print('数字参数:', num)
func(123, str = 'Python')
# 输出 >>>
TypeError: func() got multiple values for argument 'str'
3. 默认参数
相对于上面两种传入参数的方式,默认参数在实际调用函数的时候可以不必一定要给相对应已经指定默认值的参数传入值,因为如果不对这个指定默认值的参数传入值,那 Python 也能知道,不传入的参数可以使用指定的默认值来继续下去。
def func(str, num=123):
print('字符串参数:', str)
print('数字参数:', num)
func('Python')
# 输出 >>>
字符串参数: Python
数字参数: 123
4. 不定长参数
不定长参数是以带星号的参数来表示 param ,这个代表传入的参数可以有一个或多个,也可以是不传参数,传入的参数类型也没有限定。最后在函数中如果打印出来,可以发现不定长参数最后是一个元组类型的数据。
def func(str, *args):
print('字符串参数:', str)
print('不定长参数:', args)
func('Python', 456, 89.3, 'Java')
# 输出 >>>
字符串参数: Python
不定长参数: (456, 89.3, 'Java')
# ================================================================
def func2(str, *args):
print('字符串参数:', str)
print('不定长参数:', args)
func2('Python')
# 输出 >>>
字符串参数: Python
不定长参数: ()
这边提到了不定长参数是带一个星号的,Python 中其实有带两个星号的参数,这个带两个星号的参数可以接收多个关键字参数,两个函数可以一起使用,但是使用顺序是规定好的,不定长参数一定要在带两个星号参数的前面。
def func(str, *args, **param):
print('字符串参数:', str)
print('不定长参数:', args)
print('字典类型参数:', param)
func('Python', 456, 89.3, 'Java', a = 1, b = 2, c = 3)
# 输出 >>>
字符串参数: Python
不定长参数: (456, 89.3, 'Java')
字典类型参数: {'a': 1, 'b': 2, 'c': 3}
可以看到上面的例子中,最后通过传入多个关键字参数,在函数中被转换成了字典类型。
二、匿名函数
Python 使用 lambda
来创建匿名函数,匿名函数只能在有限的情况下使用,因为匿名函数只能是单个表达式,并不能像普通函数一样包含代码块。下面看一下匿名函数和普通函数的对比。
# 普通函数
def sum(a, b):
return a + b
print(sum(1, 2))
# 输出 >>>
3
# 匿名函数
sum = lambda a, b: a+b
print(sum(1, 2))
# 输出 >>>
3
从上面两个例子来看,匿名函数的调用方式其实是和普通函数一样的,同时可以看到 lambda
的格式其实很简单,分为三个部分:lambda
关键词,参数以及表达式。表达式里面不能添加大量的代码块,所以在使用的时候只能将有限的逻辑添加进去。
lambda [arg1 [,arg2,.....argn]]:expression
总结
这边主要介绍了函数的基本定义,以及函数各项参数的类型,参数可以在函数中混合使用,并不一定要求一定要是具体某一种。函数的定义比较简单,重要的是,在 Python 中一定要注意函数中代码的格式,不能每一行都顶着最左边写,因为 Python 有着很严格的格式检查,如果格式不一样,出来的结果可能也会不一样。