Python中,函数是一段可以重复使用的代码块,用于执行特定的任务。函数可以接受输入参数,并且可以根据这些参数返回输出。定义函数有助于组织代码,提高代码的可读性和可维护性。使用函数还可以避免重复代码,使得代码更加简洁。
Python中的函数通过def关键字来定义,后面跟函数名和括号,括号中可以包含参数。函数体以冒号开始,并且通常需要缩进。
-
概念
函数是可以重复执行的语句块,可以重复调用
-
作用
用于封装语句块,提高代码的重用性。 -
定位
函数是面向过程编程的最小单位
1、函数的定义
def 函数名(参数1, 参数2, ...):
函数体
return 返回值(可选)
def是定义函数的关键字。函数名是你为函数指定的名称。参数是可选的,可以传入一个或多个参数给函数。函数体包含了函数的具体执行代码,通常需要缩进。return也是可选的,用于返回函数的结果。如果没有返回值,函数默认返回None
例子
# 函数定义:
def my_func(x, y):
return x + y
def my_func2(x, y, z):
a = x + y+ z
return a
2、调用函数
语法:
函数名(实际调用传递参数)
#无参数
def g():
a = 10
b = 20
c = a + b
print(c)
def h():
a = 10
b = 20
c = a + b
return c
#函数调用
f()
g()
h= h() #将函数的返回值赋给变量h
print(h)
#有参数
def fn(x):
return x**2 + 2*x + 1
def fn1(a,b):
return (b**2 - a**2)/(2*(b-a))
print(fn(2))
print(fn1(1,3))
2.1 调用传参
函数调用时传递参数的方式有多种,包括位置传参、关键词传参、多个参数解包、参数默认值等。
2.1.1位置传参:
最常见的传参方式,参数按定义的顺序依次传入函数。
def greet(name, age):
print(f"Hello, {name}. You are {age} years old.")
greet("Alice", 30) # name="Alice",age="30"
2.1.2关键词传参
通过指定参数的名称来传值,无顺序限制,代码可读性较高。
def fun(a,b,c):
print("a=",a)
print("b=",b)
print("c=",c)
fun(c=3,b=2,a=1)
2.1.3参数默认值
定义函数时可为某些参数指定默认值,如果不传参则使用默认值。默认值参数必须位于无默认值参数的后面。
def fun(a,b=10):
print(a+b)
fun(5)
def f(a,b=10,c): #这样不行,默认值必须在无默认值后,def f(a,c,b=10)
2.1.4 可变位置参数
使用 *args 可让函数接受任意数量的位置参数。*args 会将多余的位置参数收集成一个元组。
def fun(a,b=10):
print(a+b)
fun(5,12,34) #传入的参数的数量不对,报错
def fun(a,b,*c):
print("a=",a,"b=",b,"c=",c)
fun(1,2,3,4,5,6,7,8,9,10) #a= 1 b= 2 c= (3, 4, 5, 6, 7, 8, 9, 10)
2.1.5可变关键词参数
使用 $**kwargs$ 可以让函数接受任意数量的关键词参数。$**kwargs$ 会将多余的关键词参数收集成一个字典。
def fun(**c):
print(c)
fun(name='张三',age=20,sex='男',salary=10000)
#{'name': '张三', 'age': 20, 'sex': '男', 'salary': 10000}
2.2 多参数解包
Python 允许在调用函数时解包序列或字典,使其作为位置参数或关键词参数传递给函数。
2.2.1解包位置参数
使用 * 解包
def f(a,b):
print("a=",a)
print("b=",b)
l = ["hello", "world"]
f(*l) # 解包
# a= hello
# b= world
2.2.2解包关键词参数
使用 ** 解包
# **解包
def fn(a,b,c):
print(a,b,c)
s = {'a':100, 'b':200, 'c':300}
fn(**s) # 解包
#100 200 300
3、可变和不可变参数
在 Python 中,实参可以是可变类型或不可变类型。它们的区别主要体现在值传递和引用传递的行为上。
3.1 不可变类型
不可变类型包括:int、float、str、tuple、frozenset 等。
传递方式是值传递: 传递给函数的是该对象的值,函数内部修改该值不会影响外部变量的值。
def modify(x):
print('修改之前:x=', x, "id=", id(x))
x = 10 # 修改了 x 的值,但不会影响外部变量
print('修改之后:x=',x, "id=", id(x))
a = 5
modify(a)
print('原始数据:x=',a, "id=", id(a))
# 修改之前:x= 5 id= 140718916635192
# 修改之后:x= 10 id= 140718916635352
# 原始数据:a= 5 id= 140718916635192
3.2可变类型
可变类型包括:list、dict、set$ 等。这些类型的对象可以在原地修改。
传递方式是**引用传递** :传递给函数的是对象的引用(即内存地址),在函数内部修改该参数的内容会直接影响外部变量。
def modify(lst):
print('修改之前:', lst, id(lst))
lst.append(4) # 修改了 lst 对象的内容
print('修改之后:',lst, id(lst))
a = [1, 2, 3]
modify(a)
print('外部原始数据:',a, id(a))
#修改之前: [1, 2, 3] 2123053058816
#修改之后: [1, 2, 3, 4] 2123053058816
#外部原始数据: [1, 2, 3, 4] 2123053058816
4、匿名函数
匿名函数是没有名字的函数,通常用于需要一个简短的、临时的函数场景,它可以有任意数量的参数,但只能包含一个表达式,并返回该表达式的结果。
lambda arguments: expression
arguments:一个或多个输入参数,可以是位置参数或关键词参数。
expression:一个单一的表达式,它的值将作为返回值返回。
# 定义一个 lambda 函数,接收两个参数 a 和 b,返回它们的和
add = lambda a, b: a + b
print(add(3, 5)) # 输出: 8
4.1使用场景
lambda 函数常常与高阶函数如 map()、filter() 和 sorted() 等一起使用。
处理列表
numbers = [1, 2, 3, 4, 5]
# 使用 map() 将每个数字平方
squared_numbers = list(map(lambda x: x ** 2, numbers))
print(squared_numbers) # 输出: [1, 4, 9, 16, 25]
筛选列表
numbers = [1, 2, 3, 4, 5, 6]
# 使用 filter() 筛选出偶数
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # 输出: [2, 4, 6]
实现排序
# 按照字典的值排序
dict_list = [{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}, {"name": "Charlie", "age": 35}]
# 按照 age 排序
sorted_dict_list = sorted(dict_list, key=lambda x: x["age"])
print(sorted_dict_list)
# 输出: [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]
4.2条件表达式
# 判断是否为偶数
is_even = lambda x: "Even" if x % 2 == 0 else "Odd"
print(is_even(4)) # 输出: Even
print(is_even(7)) # 输出: Odd
4.3匿名函数优点
-
结构简单:
lambda函数通常用在需要一个短小函数的地方,而普通函数则更适合复杂的逻辑。 -
匿名性:
lambda函数是没有名字的,它们通常只在一个地方使用,并且不需要被重复调用。 -
功能限制:
lambda函数只能包含一个表达式,不可以包含多行语句,而普通函数可以包含多行代码、条件判断、循环等复杂逻辑。
5、变量作用域
在Python中,变量作用域指的是变量在程序中可被访问的区域。Python主要有四种变量作用域:
-
局部作用域(Local Scope):在函数内部定义的变量具有局部作用域,只能在该函数内部访问。例如,在
f1(a, b)和f2(a, b)中,a和b都是局部变量,只能在各自的函数内部使用。 -
嵌套作用域(Enclosing Scope):在嵌套函数中,如果内部函数引用了外部函数的变量,这些变量既不是局部变量也不是全局变量,而是位于嵌套作用域中。例如,如果在
fn(x, y, fun)内部再定义一个函数,并引用x或y,那么x和y在这个新定义的函数中就是嵌套作用域的变量。 -
全局作用域(Global Scope):在函数外部定义的变量具有全局作用域,可以在整个程序中访问,包括在所有函数内部。但是,如果要在函数内部修改全局变量的值,需要使用
global关键字声明。 -
内置作用域(Built-in Scope):这是Python的内置作用域,包含所有内置函数和变量。这个作用域对所有模块都是可见的,但在用户定义的全局作用域和局部作用域中定义的同名变量会覆盖内置作用域的变量。
5.1局部作用域
-
指函数或方法内部定义的变量。
-
仅在函数内部有效,函数外部无法访问。
-
在函数调用时被创建,在函数调用后自动销毁。
#局部变量
def func():
a = 10 #局部变量
b = 20 #局部变量
c = a + b
print(c)
print(a) #报错:NameError: name 'a' is not defined
#函数内的变量a、b、c都是局部变量,只能在函数内使用,不能在函数外访问。
5.2嵌套作用域
-
指外层函数中的变量,在内层函数中可访问,但不可修改。
-
当一个函数嵌套在另一个函数内部时,外层函数的变量属于Enclosing作用域。
def outer():
x = 20 # 外层函数变量
def inner():
print(x) # 访问外层函数变量
inner()
nonlocal:将局部作用域中变量声明为外部嵌套函数作用域中的变量
#外部嵌套作用域
def func01():
a = 10
def func02():
# 内部函数,如果修改外部嵌套变量,需要使用nonlocal语句声明
nonlocal a
a += 20
func02()
print(a)
func01()
5.3 全局作用域
指模块级别定义的变量,整个模块都可以访问。
如果想在函数中修改全局变量,需要使用`global`关键字。
示例:如何用一个变量来记录一个函数调用的次数
a = 100 #全局变量
def func2():
global a #声明全局变量
a = 200 #修改全局变量
print("a =", a)
func2()
print("a =", a) #200
# a = 200
# a = 200
5.4 内建作用域
包含Python内建的函数、异常和常量,如`print()`, `len()`, `int`, `Exception`等。
这些变量可以在任何地方使用。
print(len([1, 2, 3])) # 使用内建函数len
6、内置函数
Python提供了大量的可直接使用的内置函数,主要执行一些常见的操作:数据处理、类型转换、数学计算、输入输出等。
官方地址:https://docs.python.org/zh-cn/3.13/library/functions.html
1.all()
如果可迭代对象中的所有元素都为 True,返回 True,否则返回 False。
print(all([True, True, False])) # 输出: False
print(all([1, 2, 3])) # 输出: True
2.sum()
返回可迭代对象中所有元素的总和。
print(sum([1, 2, 3])) # 输出: 6
3.sorted()
返回一个新列表,其中包含可迭代对象中的元素,按照升序排序。
print(sorted([3, 1, 2])) # 输出: [1, 2, 3]
4.reversed()
返回一个反向迭代器。
print(list(reversed([1, 2, 3]))) # 输出: [3, 2, 1]
5.callable()
检查对象是否可以被调用(即是否是函数或方法)。
print(callable(print)) # 输出: True
print(callable(123)) # 输出: False
6.zip()
将多个可迭代对象打包成一个元组,常用于并行遍历多个序列。
names = ["Alice", "Bob"]
ages = [25, 30]
zipped = zip(names, ages)
print(list(zipped)) # 输出: [('Alice', 25), ('Bob', 30)]
7.eval()
将字符串作为有效的 Python 表达式来执行,并返回结果。
x = 10
result = eval("x + 5")
print(result) # 输出: 15
8.exec()
执行存储在字符串中的 Python 代码。
code = 'for i in range(3): print(i)'
exec(code)
# 输出:
# 0
# 1
# 2
9.globals() 和 locals()
globals() 返回当前全局符号表(一个字典);locals() 返回当前局部符号表(也是字典)。
x = 10
print(globals()) # 输出: 包含全局变量的信息
print(locals()) # 输出: 包含局部变量的信息
10.filter()
从可迭代对象中过滤出符合条件的元素。
numbers = [1, 2, 3, 4, 5]
filtered = filter(lambda x: x % 2 == 0, numbers)
print(list(filtered)) # 输出: [2, 4]
7、高阶函数
高阶函数是指可以接受一个或多个函数作为参数,或者返回一个函数作为结果的函数。
7.1常见高阶函数
1 map
map(function, iterable)
map函数:
-
接受一个函数和一个可迭代对象
-
将接受的函数应用到可迭代对象的每个元素上
-
返回一个包含结果的迭代器
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
# squared现在包含[1, 4, 9, 16, 25]
2 filter
filter(function, iterable)
filter函数:
-
接受一个函数和一个可迭代对象
-
用接受的函数来筛选出可迭代对象中满足条件的元素
-
返回一个包含满足条件的元素的迭代器
numbers = [1, 2, 3, 4, 5]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
# even_numbers现在包含[2, 4]
3 reduce
reduce(function, iterable[, initializer])
reduce函数:
-
reduce函数接受一个函数和一个可迭代对象
-
将接受的函数累积地应用到可迭代对象的元素上
-
可选的 initializer 参数可以作为累积的初始值
from functools import reduce
numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
# product现在包含120 (1 * 2 * 3 * 4 * 5)
7.2作为参数
高阶函数可以接受其他函数作为参数,用于自定义行为。
def sort_custom_key(item):
return item[1]
data = [('apple', 3), ('banana', 1), ('cherry', 2)]
sorted_data = sorted(data, key=sort_custom_key)
# sorted_data现在包含[('banana', 1), ('cherry', 2), ('apple', 3)]
2243

被折叠的 条评论
为什么被折叠?



