深入理解 Python 中的函数
简介
在编程中,函数是组织和复用代码的基本单元。Python 作为一门高级编程语言,提供了丰富的函数特性来帮助开发者编写清晰、模块化和高效的代码。在本文中,我们将深入探讨 Python 函数的定义、调用、参数、返回值、作用域等关键概念。
定义函数
函数通过 def
关键字定义。函数体开始于冒号(:)后面,并且缩进的代码块表示函数内部的语句。
def function_name(parameters):
"""函数文档字符串(docstring)"""
# 函数体
...
调用函数
一旦定义了函数,就可以通过函数名以及括号内的实际参数来调用它。
# 调用之前定义的函数
function_name(arguments)
参数和实参
函数参数是定义函数时列出的变量,而实际参数(实参)是在函数调用时传递给函数的值。Python 支持位置参数、关键字参数、默认参数、可变参数列表和可变关键字参数。
默认参数
默认参数允许你为参数指定默认值,如果调用函数时没有传递该参数,则会使用默认值。
def greet(name='World'):
print(f"Hello, {name}!")
greet() # 输出: Hello, World!
greet("Alice") # 输出: Hello, Alice!
注意:多个参数时在默认值参数右侧不能出现没有默认值的参数
def display(a,b=1,c=2):
print(a,b,c)
dispaly(1)#输出结果4
可变参数
位置参数
函数传参时,形参和实参需要一 一对应
def show(n,s):
for c in s:
print(f'{n}--{c}')
#函数调用
show(1,'hello')
#输出结果
1 -- h
1 -- e
1 -- l
1 -- l
1 -- o
不定长位置参数:通过在参数名前加星号(*),可以让函数接收不定数量的位置参数,这些参数被存储为一个元组。
def add(*args):
return sum(args)
print(add(1, 2, 3)) # 输出: 6
关键字参数
关键字参数解决了参数传递时的顺序问题,通过使用关键字和参数一一对应,可以实现无序传递
def show(n,s):
for c in s:
print(f'{n} -- {c}')
show(s='hello',n=1)
不定长关键字参数:通过在参数名前加两个星号(**),可以接收不定数量的关键字参数,这些参数被存储为一个字典。
def profile(**kargs):
for key, value in kargs.items():
print(f"{key}: {value}")
profile(name="Alice", age=30, job="Developer")
参数综合
一、定义一个可以接收任何参数的函数
def display(*args,**kwargs):
print(f'args:{args}')
print(f'kwargs:{kwargs}')
display()
display(1,2,3)
display(a=1,b=2)
display(1,2,3,4,a=1,b=2)
#位置参数不能放在关键字参数后面 因为你定义的时候把不定长位置参数放在不定长关键字参数前面的
display(a=1,b=2,2,3,4)#这行代码会报错
二、混合写法(先把abcde赋值然后关键字参数前面的都是不定长位置参数,随后定长关键字参数随后不定长关键字参数)
def func(a, b, c, d, e, *args, f=1, g=2, **kwargs):
print(a,b,c,d,e)
print(args)
print(f,g)
print(kwargs)
func(1,2,3,4,5,5,6,7,8,9,f=11,g=22,h=333,i=444)
返回值
return
语句用于从函数中返回值。如果没有 return
语句或者 return
后面没有任何值,函数将返回 None
。遇见return直接结束函数执行。
def square(number):
return number**2
result = square(4)
print(result) # 输出: 16
作用域
在 Python 中,变量的作用域是由变量定义的位置决定的。函数中定义的变量拥有局部作用域,而在函数外定义的变量则拥有全局作用域。
解释器在执行代码时,发现return 后成如果有多个值 ,那么就会将这多个值 ,直接组包成一个元组。然后将这个元组返回。
x = "global"
def func():
y = "local"
print(y) # 输出: local
print(x) # 输出: global
func()
print(x) # 输出: global
# print(y) # 错误: y 在此不可用,因为它是局部变量
文档字符串
每个函数都可以有一个文档字符串(docstring),它通常用三引号括起来。文档字符串用于解释函数的目的和如何使用它。
def greet(name):
"""向用户发出问候"""
print(f"Hello, {name}!")
函数名作为一个数据赋值给另一个对象(和引用类似)
在Python中,函数也是对象,对象就会有一个地址就会有一个引用,通过这个引用就可以找到该对象并使用它。当你将一个函数名(没有括号)赋值给另一个变量时,这个新变量将引用相同的函数对象。下面是一个例子:
# 定义了一个简单的函数
def greet(name):
return f"Hello, {name}!"
# 将这个函数赋值给另一个变量
greet_alias = greet
# 现在greet_alias引用了greet函数,你可以通过greet_alias调用这个函数
message = greet_alias("World")
print(message) # 输出: Hello, World!
在上面的代码中,greet
是一个接受一个参数的函数。我们将这个函数赋值给了 greet_alias
变量,而不是调用它(不带括号)。然后我们可以通过 greet_alias
变量来调用原来的 greet
函数。这种特性在Python中非常有用,尤其是在你需要将函数作为参数传递给其他函数时(例如,在使用高阶函数或回调函数时)。
一个常见的应用是在Python的内置函数 sorted
中,你可以传递一个函数来指定排序的依据:
# 假设我们有一个学生的列表,我们想根据年龄对其进行排序
students = [
{'name': 'Alice', 'age': 22},
{'name': 'Bob', 'age': 20},
{'name': 'Charlie', 'age': 21}
]
# 定义一个函数,它取一个学生字典并返回学生的年龄
def get_age(student):
return student['age']
# 使用sorted函数和get_age函数来对学生按年龄排序
sorted_students = sorted(students, key=get_age)
# 打印排序后的学生列表
print(sorted_students)
# 输出: [{'name': 'Bob', 'age': 20}, {'name': 'Charlie', 'age': 21}, {'name': 'Alice', 'age': 22}]
在这个例子中,get_age
函数被传递给 sorted
函数作为 key
参数。这告诉 sorted
函数应该使用 get_age
的返回值(即学生的年龄)来对学生列表进行排序。
高阶函数
在Python中,高阶函数(Higher-order function)是指那些接受函数作为参数或者返回一个函数作为结果的函数。这些函数允许我们将行为(函数)当作数据一样传递,这为编程提供了极大的灵活性和表达力。
以下是一些Python中的典型高阶函数及其使用方法的例子:
Map函数
map(function, iterable)
接受一个函数和一个可迭代对象,并对每个元素应用该函数,返回一个新的迭代对象。
def square(x):
return x * x
numbers = [1, 2, 3, 4]
squared_numbers = map(square, numbers)
print(list(squared_numbers)) # 输出: [1, 4, 9, 16]
Map函数实现原理:
def my_map(func,c_list):
#定义一个新的列表保存映射结果
new_list = []
# 遍历传入列表中的数据
for i in c_list:
#调用函数计算映射值,并保存到新列表中
n = func(i)
new_list.append(n)
return new_list
Filter函数
filter(function, iterable)
【过滤筛选】接受一个函数和一个可迭代对象,并返回一个新的迭代器,包含使该函数返回True的所有元素。
def is_even(x):
return x % 2 == 0
numbers = [1, 2, 3, 4, 5, 6]
even_numbers = filter(is_even, numbers)
print(list(even_numbers)) # 输出: [2, 4, 6]
Reduce函数
reduce(function, sequence[, initial])
不是内置函数,而是在 functools
模块中。它接受一个函数和一个序列,然后从左到右应用该函数,累积序列到单一的值。
from functools import reduce
def add(x, y):
return x + y
numbers = [1, 2, 3, 4]
result = reduce(add, numbers)
print(result) # 输出: 10 (即 1+2+3+4)
Sorted函数
sorted(iterable, key=None, reverse=False)
接受一个可迭代对象,并根据 key
函数指定的条件进行排序。
students = [
{'name': 'Alice', 'grade': 90},
{'name': 'Bob', 'grade': 80},
{'name': 'Charlie', 'grade': 70}
]
# 按成绩排序
sorted_students = sorted(students, key=lambda student: student['grade'], reverse=True)
print([{s['name']: s['grade']} for s in sorted_students])
# 输出: [{'Alice': 90}, {'Bob': 80}, {'Charlie': 70}]
Lambda函数
在Python中,匿名函数是指那些没有明确函数名的短小函数。匿名函数使用 lambda
关键字来创建,并且通常用于需要一个函数但是又不希望去正式定义一个完整函数的场景。
lambda
函数可以接受任何数量的参数,但只能包含一个表达式。这个表达式的计算结果会被这个函数自动返回。
这里是一个简单的 lambda
函数的例子:
# 使用 lambda 创建一个匿名函数
add = lambda x, y: x + y
# 调用这个匿名函数
result = add(5, 3)
print(result) # 输出: 8
在上面的例子中,lambda x, y: x + y
创建了一个接受两个参数的匿名函数,并且返回这两个参数的和。这个 lambda
函数被赋值给了变量 add
,我们可以通过这个变量来调用它。
总结
Python 中的函数是编程中不可或缺的工具,它们帮助我们以结构化和高效的方式组织代码。通过深入了解函数的各种特性,我们可以更好地管理代码的复杂性,编写出易于阅读和维护的程序。掌握 Python 函数的使用将使你在编程路上更进一步。