
Python函数详解:从基础到进阶的完整指南
Python函数详解:从基础到进阶的完整指南
函数是Python编程的基石,也是我们编写可复用、可维护代码的重要工具。在我五年的测试开发经验中,深刻理解函数的各种特性和用法,对提高代码质量起到了关键作用。
今天,我将从实际应用的角度,为大家详细介绍Python函数的方方面面,帮助大家写出更加优雅和高效的代码。
函数的参数
- 必选参数
def foo(x, y, z):
pass- 默认参数
def foo(x=1):
pass假如不传 x 参数的话, x 默认是等于1 3. 可变参数( * ) 不定长传参
# 定义:
def foo(*args):
pass
# 调用:
foo(1,2,3,4,5)元组和列表的压包
# 定义:
def foo(*args):
pass
# 调用:
foo(*(1,2,3,4,5)) or foo(*[1,2,3,4,5])- 关键字参数(
**)
定义:
def foo(**kwargs):pass
#其中 kwargs 是一个字典
#调用:
foo(k1=v1, k2=v2) # 参数传入键值对
foo(**d) # 参数传入字典d- 命名关键字参数( * )
定义:
def foo(a, b,*, k1, k2, k3):pass
# a, b是普通参数,k1, k2, k3 是命名关键字参数
# 命名关键字参数需要一个特殊分隔符 * ,后面的参数被视为命名关键字参数
# 如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要
# 一个特殊分隔符 * 了
# 调用
foo(a, b, k1=v1, k2=v2, k3=v3)
foo(a, b, *(1, 2, 3), k1=v1, k2=v2, k3=v3)
foo(a, b, *(1, 2, 3), **{'k1': v1, 'k2': v2, 'k3': v3})- 参数组合 在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
定义:
def fun(parameter,*args,keyparameter,**kwargs):
pass
# 参数定义顺序:必选参数,默认参数,可变参数,命名关键字参数,关键字参数
# 调用:
fun(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)函数作用域
- 外部不能访问函数内部变量
- 函数内部能够访问外部变量
- 函数内部不能修改外部变量,强行修改需要 global 外部变量 = 新值
- 函数内部和函数外部变量名可以相同,但需要注意访问优先级 参考文献:
知识点1:全局作用域
定义:
x = 1
def foo():
pass
# 调用:
print(x)- 知识点2:局部作用域
定义:
def foo():
x = 1
pass
# 调用:
foo()
print(x) # 报错知识点3:闭包 在 Python 中,闭包(Closure)是一个函数对象,闭包就是能够读取外部函数内的变量的函数。比如我们调用a函数,a函数返回了b函数,而b函数能够读取a函数的变量,那么b函数就是一个闭包。
闭包的特征:嵌套函数
闭包是一个嵌套在另一个函数内的函数。 自由变量:
闭包可以访问外部函数的局部变量,这些变量被称为自由变量。 保持状态:
闭包可以记住其外部函数的状态,即使外部函数已经返回。 创建闭包的步骤 定义一个外部函数。 在外部函数中定义一个内嵌的函数。 在外部函数中返回这个内嵌的函数。
def outer_function(x):
def inner_function(y):
return x + y
return inner_function
# 创建闭包
closure = outer_function(10)
# 调用闭包
result = closure(5) # 结果是 15
print(result)解释
在上面的例子中,outer_function 是外部函数,它接受一个参数 x。
inner_function 是嵌套在 outer_function 内部的函数,可以访问 x。
当我们调用 outer_function(10) 时,它返回了 inner_function,并且这个返回的函数保留了对 x 的引用。
即使 outer_function 已经执行完毕,closure 仍然可以使用 x 的值。
- 知识点4: nonlocal nonlocal 关键字用来在函数或其他作用域中使用外层(非全局)变量。
定义:
def foo():
x = 1
def bar():
nonlocal x
x = 2
bar()
print(x)
# 调用:
foo()函数式编程
- 什么是函数式编程 把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。 可以简单的理解为,我们调用一个函数,参数的传入为另一个函数,这个函数就叫做高阶函数。而这个函数的参数,我们就叫做回调函数。这种编程方式,就是函数式编程。
高阶函数
Python中常见的高阶函数有:map()、reduce()、filter()、sorted()。
说到Python的高级函数,我们也顺带提一下lambda函数。
lambda函数
lambda函数是一种匿名函数,它可以接受任意数量的参数,但只能有一个表达式。lambda函数通常用于需要一个简单函数的地方,例如作为参数传递给其他函数。 lambda函数的语法如下:
lambda arguments: expressionarguments:表示函数的参数,可以是多个,用逗号分隔。 expression:表示函数的返回值,只能是一个表达式。 lambda函数的示例:
# 定义一个简单的lambda函数,将两个数相加
add = lambda x, y: x + y
# 调用lambda函数
result = add(3, 5)
print(result) # 输出:8在上面的示例中,我们定义了一个简单的lambda函数add,它接受两个参数x和y,并返回它们的和。然后,我们调用lambda函数add,并将结果赋值给变量result。最后,我们打印result的值,输出结果为8。 lambda函数的特点:
- 匿名函数:lambda函数没有名称,它是一种匿名函数,不需要使用def关键字来定义。
- 简洁:lambda函数通常用于简单的操作,它的语法非常简洁,只需要一个表达式。
- 函数式编程:lambda函数通常用于函数式编程,它可以作为参数传递给其他函数。
- 不能包含复杂的语句:lambda函数不能包含复杂的语句,只能包含一个表达式。
- 不能包含赋值语句:lambda函数不能包含赋值语句,例如x = 1。
- 不能包含return语句:lambda函数不能包含return语句,它的返回值是表达式的结果。
- 不能包含yield语句:lambda函数不能包含yield语句,它不能作为生成器函数使用。
map函数
map(function, iterable)
> function -- 函数
> iterable -- 序列示例
def add(x):
return x**2 #计算x的平方
lists = range(11) #创建包含 0-10 的列表
a = map(add,lists) #计算 0-10 的平方,并映射
print(a) # 返回一个迭代器:<map object at 0x0000025574F68F70>
print(list(a)) # 使用 list() 转换为列表。结果为:[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# 使用lambda匿名函数的形式复现上面的代码会更简洁一些
print(list(map(lambda x:x**2,range(11)))) # 结果为:[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]filter
filter(function or None, iterable)function:函数,作用是对iterable中的每个元素判断是否符合特定条件。 None:不调用任何函数,只对可迭代对象中的元素本身判断真假,保留为真的元素。 iterables:可迭代对象(序列、字典等)。
filter函数实例
求一个序列中大于零的元素组成的新序列
我们先来看下filter函数不加list的结果,代码如下:
c = [-10, 28, 9, -5, 30, 5]
filter(lambda a:a>0, c)
# 得到结果:
<filter at 0x27950dbb9d0>返回一个惰性计算的filter对象或迭代器。接下来看下用list函数进行转换会得到什么,代码如下:
c = [-10, 28, 9, -5, 30, 5]
list(filter(lambda a:a>0, c))
# 得到结果:
[28, 9, 30, 5]从结果知,filter函数的作用是挑选出了序列c中大于0的元素组成了新的对象或迭代器。通过list函数进行转换,进而得到符合条件的元素组成的新列表。
reduce
reduce(function, iterable[, initializer])function:函数,作用是对iterable中的每个元素进行操作,返回一个值。 iterables:可迭代对象(序列、字典等)。 initializer:可选参数,初始值。 reduce函数实例 求一个序列中所有元素的和 我们先来看下reduce函数不加list的结果,代码如下:
from functools import reduce
c = [-10, 28, 9, -5, 30, 5]
reduce(lambda a,b:a+b, c)
# 得到结果:
10reduce函数的作用是对序列c中的元素进行操作,返回一个值。在这个例子中,我们使用lambda函数对序列c中的元素进行求和操作,返回结果为10。 我们再来看下reduce函数加上list的结果,代码如下:
from functools import reduce
c = [-10, 28, 9, -5, 30, 5]
list(reduce(lambda a,b:a+b, c))
# 得到结果:
TypeError: 'int' object is not iterable从结果知,reduce函数返回的是一个int类型的值,而不是一个可迭代对象。因此,我们不能直接使用list函数进行转换,需要先将其转换为可迭代对象,然后再使用list函数进行转换。
- 一句话解决阶乘函数?
from functools import reduce
reduce(lambda x,y:x*y,range(1,6))sorted
sorted(iterable, key=None, reverse=False)iterable:可迭代对象(序列、字典等)。 key:可选参数,用于指定排序的关键字。 reverse:可选参数,用于指定排序的顺序,默认为升序。 sorted函数实例 对一个序列进行排序 我们先来看下sorted函数不加list的结果,代码如下:
c = [-10, 28, 9, -5, 30, 5]
sorted(c)
# 得到结果:
[-10, -5, 5, 9, 28, 30]sorted函数的作用是对序列c进行排序,返回一个新的序列。在这个例子中,我们使用sorted函数对序列c进行排序,返回结果为一个新的序列。 我们再来看下sorted函数加上list的结果,代码如下:
c = [-10, 28, 9, -5, 30, 5]
list(sorted(c))
# 得到结果:
[-10, -5, 5, 9, 28, 30]从结果知,sorted函数返回的是一个新的序列,而不是一个可迭代对象。因此,我们可以直接使用list函数进行转换,得到一个新的序列。
