四、函数
函数是执行特定任务的一段代码,程序通过将一段代码定义成函数,并为该函数指定一个函数名,这样即可在需要的时候多次调用这段代码。 比如我们前面学到的range() 函数,就是系统内置的函数,功能是通过传入参数,返回特定范围的数字序列,函数名是range,我们在需要的时候,可以多次调用。
1. 函数的定义
函数的定义语法:
def 函数名(形参列表):
函数体 (由零条到多条可执行语句组成的函数)
return 返回值
- 函数名要符合标识符定义,取名的时候要有意义,见名知义。
- 形参列表是定义该函数可以接受的参数,多个参数都逗号隔开,调用函数的地方传入对应的参数值。
最基础函数定义,以及调用:
def say_helloworld():
print("看到python就说,你好!")
# 调用函数
say_helloworld()
# 第二次调用函数
say_helloworld()
执行结果:
2. 函数的参数
函数形参部分,可以不定义参数,直接空括号即可。假如有多个参数,逗号隔开。 我们调用的时候,传入的就是实际参数,按照形参定义,顺序传入即可。 我们看下面这个实例:
# 定义加方法函数
def add(x, y):
result = x + y
print(f"{x}+{y}={result}")
# 调用函数
add(1, 2)
add(2, 3)
add(3, 4)
执行结果:
关键字(keyword)参数
前面实例,是位置参数,调用的时候,必须严格按照定义函数时指定的顺序来传入参数值。 如果根据参数名来传入参数值,则无需遵守定义形参的顺序,这种方式被称为关键字(keyword)参数 。
在使用关键字参数的时候,顺序可以随便换
部分使用关键字参数,部分使用位置参数
混用的时候,关键字参数必须位于位置参数之后,否则报错
# 根据关键字参数来传入参数值
add(x=1, y=2)
# 在使用关键字参数的时候,顺序可以随便换
add(y=2, x=1)
# 部分使用关键字参数,部分使用位置参数
add(1, y=2)
# 混用的时候,关键字参数必须位于位置参数之后,否则报错
add(x=1, 2)
参数默认值
在某些情况下,程序需要在定义函数时为一个或多个形参指定默认值——这样在调用函数时就可以省略为该形参传入参数值,而是直接使用该形参的默认值。
语法格式:
形参名=默认值
案例:
def say_hi(name="李白", msg="大河之水天上来"):
print(f"{name}说:{msg}")
say_hi()
执行结果:
- 可以全部使用默认参数
- 可以部分使用默认参数
- 可以全部不使用默认参数
- 假如前面参数使用默认参数,后面的参数需要使用关键字参数
- Python要求将带有默认值的参数定义,放在形参列表的最后。
# 全部使用默认参数
say_hi()
# msg使用默认值
say_hi("小王")
# 两个参数都不使用默认值
say_hi("李四", "我去你家")
# name使用默认值,msg需要使用关键字参数
say_hi(msg="也喜欢java")
执行结果:
3. 函数的返回值
函数执行完毕,可以返回数据给方法的调用者。(可以返回多个数据),通过return关键字
例如:
# 定义加方法函数
def add(x, y):
result = x + y
# 通过return关键字,把x+y的结果返回给函数的调用者
return result
# 定义变量r,接收函数的返回值
r = add(1, 2)
print(f"调用add(1, 2)的返回结果是{r}")
r2 = add(2, 3)
print(f"调用add(2, 3)的返回结果是{r2}")
执行结果:
如果程序需要有多个返回值,则既可将多个值包装成列表之后返回,也可直接返回多个值。如果Python函数直接返回多个值,Python会自动将多个返回值封装成元组。(后续讲到元组,我们给下实例讲解下)
如果函数没有使用return语句返回数据,则函数返回的是None 值。None是空的意思。
案例:
def say_helloworld():
print("Python很好学")
result = say_helloworld()
print(f"返回结果{result},类型{type(result)}")
执行结果:
上面案例等同于return None
# 定义最基础函数 helloworld
def say_helloworld():
print("Python大爷你好,学Python,上www.python222.com")
return None
result = say_helloworld()
print(f"返回结果{result},类型{type(result)}")
①可以用于if判断
def check_user(userName, password):
if userName == 'python' and password == '123456':
return "success"
else:
return None
result = check_user('python', '123')
print(f"返回结果{result}")
# 1,可以用于if判断
if not result:
print("登录失败")
②可以用于声明无初始化内容的变量
# 2,可以用于声明无初始化内容的变量
userName = None
4. 函数的说明文档
用""" """备注说明,然后我们调用函数的地方,鼠标移动上去就能看到函数的说明。提供代码的可读性。
def add(x, y):
"""
两数相加函数
:param x: 两数相加数x
:param y: 两数相加数y
:return: 两数相加的结果
"""
return x + y
print(add(1, 2))
显示结果:
5. 变量作用域
在程序中定义一个变量时,这个变量是有作用范围的,变量的作用范围被称为它的作用域。根据定义变量的位置,变量分为两种。
- 局部变量。在函数中定义的变量,包括参数,都被称为局部变量。
- 全局变量。在函数外面、全局范围内定义的变量,被称为全局变量。
局部变量:
def test():
name = "jack"
# 定义局部变量name
print(name)
test()
# 局部变量,外面无法使用
print(name)
全局变量:
def test():
name = "jack"
# 定义局部变量name
print(name)
test()
# 局部变量,外面无法使用
# print(name)
# 打印全局变量
print(name2)
使用global关键字声明全局变量:
def test():
name = "jack"
# 定义局部变量name
print(name)
# 声明全局变量name2
global name2
name2 = "Marry"
test()
# 局部变量,外面无法使用
# print(name)
# 打印全局变量
print(name2)
执行结果:
6. 递归函数
在一个函数体内调用它自身,被称为函数递归。函数递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
实例,求1+2+3+..+100的和,用递归实现。数学公式:f(n)=n+f(n-1)
def cal(n):
if n == 1:
return 1
return n + cal(n - 1)
print(cal(100))
执行结果: 5050
递归算法,必须要有一个递归出口条件,否则无限死循环