在Python中,函数是一段被命名的代码块,它执行特定的任务并可能返回结果。函数可以带有参数,也可以不带参数,并可以在代码中被多次调用。通过使用函数,我们可以提高代码的可读性、可维护性和复用性。
1、函数的定义
函数的定义使用def关键字,后面跟着函数名和一对圆括号(),括号内可以包含参数列表,然后是冒号:,最后是一个代码块(即缩进的代码部分)。
基本语法如下:
def 函数名([参数1, 参数2, ...]):
代码
[return 表达式]
其中函数名可以是字母、数字或下划线组成的字符串,但是不能以数字开头。
函数的参数放在一对圆括号中,参数的个数可以有零个、一个或多个,参数之间用逗号隔开,这种参数称为形式参数。
括号后面以冒号结束,冒号下面就是函数的主体。
返回值不是必须的,很多函数可能没有返回值。
如下面的例子所示:
def greet():
print("Hello,我叫张三!")
在这个例子中,我们定义了一个名为greet的函数,它接受一个参数name。函数体内部有一行代码,使用print函数打印出一条问候信息。
2、函数的调用
定义了函数之后,我们需要通过函数名加上圆括号以及必要的参数来调用它。
注意:即使函数不需要参数,调用参数时,也要在函数名后使用一对空的圆括号。
greet() # 输出: Hello, 我叫张三!
这里成功调用了greet函数,打印出了里面的内容。从程序执行上说,虽然达到了效果,但是不够灵活,如果想要打印出其他人名,就需要去修改源代码,这样就会很麻烦,因此在定义的时候可以让函数接收数据,这样的使程序变得比较灵活。
3、函数参数
(1)形参和实参
在def语句中函数名后面圆括号中的参数称为形参,而调用函数时指定的参数称为实参。
def greet(name):
print(f"Hello,{name}!")
greet('李四') # 输出: Hello, 我叫李四!
上面程序中,name就是形参,'李四'就是实参。
(2)位置参数
函数调用时,实参默认按位置顺序传递,需要个数与形参匹配。按位置传递的参数被称为“位置参数”。例如
def calculate_sum(a, b, c):
return print(a + b + c)
calculate_sum(3, 4, 6) # 输出: 13
calculate_sum(3, 4) # 报错,位置参数数量不匹配
(3)默认参数
在Python中,可以在声明函数时,预先为参数设置一个默认值。当在调用函数时,如果某个参数具有默认值,则可以不向函数传递该参数的值。这个参数就被称为“默认参数”。例如:
def calculate_sum(a, b, c=10, d=5):
return print(a + b + c - d)
calculate_sum(3, 4) # 输出: 12
calculate_sum(3, 4, 5) # 输出:7
calculate_sum(3, 4, 5, -3) # 输出:15
(4)关键字参数
在传递参数时不仅可以按照声明函数时参数的顺序进行传递,还可以按照形参的名称传递参数,称为“关键字参数”,也叫“命名参数”。
使用关键字参数传递值时,要在调用函数名后的圆括号里为函数的所有参数赋值,赋值的顺序可以不按照函数声明的参数顺序。例如:
def calculate_sum(a, b, c):
return print(a + b + c)
calculate_sum(3, 4, 5) # 输出:12
calculate_sum(b=4, a=3, c=5) # 输出: 12
calculate_sum(3, 4, b=5) # 报错,使用关键字参数并不按顺序传递值时,必须指定全部参数
calculate_sum(3, 4, c=5) # 12
(5)可变参数
在Python中,函数可以具有任意个参数,而不必再声明函数时对所有的参数进行定义。
只需在声明函数时,在参数名前加一个星号“*”,则可以表示将多个参数收集到一个“元组”对象中;
如果在参数名前加上两个星号,则表示将多个参数收集到一个“字典”对象中。
当我们在定义一个函数,并且不能确定参数的个数时,这种方法就很好用。
def add_numbers(*args):
print(args)
return sum(args)
result = add_numbers(1, 2, 3, 4) # 输出: (1, 2, 3, 4)
print(result) # 输出: 10
def print_numbers(a, b, *args):
return print(a, b, args)
print_numbers(1, 2, 3, 4) # 输出: 1, 2, (3, 4)
在这个例子中,add_numbers、print_numbers函数使用*args来接收任意数量的位置参数,并将它们作为一个元组处理。
如果用两个星号的话,可变参数则以字典的形式体现。
def greet_people(**kwargs):
for name, greeting in kwargs.items():
print(f"{greeting}, {name}!")
greet_people(Alice="Hello", Bob="Hi") # 输出: # Hello, Alice! # Hi, Bob!
在这个例子中,greet_people函数使用**kwargs来接收任意数量的关键字参数,并将它们作为一个字典处理。然后,函数遍历这个字典并打印出每个人的问候语。
(6)强制命名参数
使用可变参数需要考虑形参位置的问题,如果在函数中,既有普通参数,也有可变参数,通常可变参数会放在最后,如上面的实例。
其实可变参数也可以放在函数参数的中间或最前面,只是在调用函数时,可变参数后的普通参数要使用关键字参数形式来传递。
强制命名参数的使用一
def fun1(*a, b, c):
print(a, b, c)
# fun1 (2, 3, 4) # 会报错,由于 a 是可变参数,2,3,4 将会全部传递给a,造成 b 和 c 没有赋值。
fun1(2, b=3, c=4) # 可变参数放在最前面,其他参数使用关键字参数形式传递
def fun2(a, *b, c):
print(a, b, c)
fun2('hello', 2, 3, 4, 5, c='end') # 可变参数放在中间,后面的参数使用关键字参数形式传递
如果可变参数在函数参数的中间位置,而且在为可变参数后面的普通参数传值时也不想使用关键字参数,那么就必须为这些普通参数指定默认值。
强制命名参数的使用二
# 可变参数放在中间位置,调用函数时候不想使用关键字参数形式传递参数,则普通参数必须有默认值
def fun1(a,* b, c=10, d=20):
print(a, b, c, d)
fun1('hello', 'Python', 'I', 'Love', 'You') # hello ( 'Python', 'I', 'Love', 'You') 10 20
如果可变参数在函数参数的中间位置,并且没有为可变参数后面的普通形式参数指定默认值,在调用时也未使用关键字参数指定这些形参的值,那么调用函数时会抛出错误。
强制命名参数的使用三
def fun1(a, *b, c, d):
print(a, b, c, d)
fun1('hello', 'Python', 'I', 'Love', 'You') # 报错
4、返回值
函数可以返回一个或多个值。如果函数没有显式地使用return语句,那么它默认返回None。
def get_largest(a, b):
if a > b:
return a
else:
return b
largest = get_largest(5, 10)
print(largest) # 输出: 10
在这个例子中,get_largest函数比较两个数的大小,并返回较大的那个数。
5、局部变量与全局变量
在函数内部定义的变量是局部变量,它们只在函数内部可见。而在函数外部定义的变量是全局变量,可以在整个程序中访问。
在函数内部,可以访问全局变量,但通常不推荐修改全局变量,除非有明确的理由。
在嵌套函数中,如果内部函数想修改外部函数变量的值,就可以使用nonlocal关键字。
global_var = 10
def modify_global():
global global_var # 声明我们要修改的是全局变量
global_var = 20
outer_var = 20
def inner():
nonlocal outer_var
print('inner outer_var:', outer_var)
outer_var = 10
inner()
print('outer outer_var:', outer_var)
modify_global()
print(global_var) # 输出: 20
在这个例子中,我们定义了一个全局变量global_var,并在modify_global函数内部使用global关键字声明我们要修改的是全局变量。
同时,inner为嵌套函数中的内部函数,outer_var为外部函数的变量,内部函数在修改外部函数变量时,就需要用到nonlocal关键字。
关注公众号,获取200+本Python、人工智能相关学习资料