1. 函数的概念
在Python中,函数是一块可重复调用的代码。 在编写代码时,如果有一块代码需要在程序的多个地方使用,那么这个时候就可以将这块代码封装为一个函数。
函数通过名称来调用,它可以接受输入(称为参数)并产生输出结果。
因此,函数的作用就是可以让我们复用一段需要重复使用的、独立的代码块。
2. 定义函数
在Python中定义一个函数,可以使用关键字def
,它后面紧跟着函数名、括号以及冒号,如下:
def function_name():
# function_code
例如,以下代码定义了一个名为hello_world
的函数:
def hello_world():
print('Hello World!')
这个函数不接收任何参数,执行时,只会输出一句话:“Hello World!”
如果希望函数接收参数,则可以在括号内指定参数。
def func_name(arg1, arg2, ...):
# function_code
接下来,看一个示例:
def square(x):
return x * x
这个函数名为square
,它接收一个参数x
,返回值是x
的平方。
使用return
关键字返回一个值。如果没有给出返回值,Python会返回一个特殊的变量值None。
3. 调用函数
在定义函数后,我们可以通过调用函数来执行其中的代码。调用函数,只需要在其后面添加一对括号,并传递需要的参数即可。
例如,要调用我们上面定义的hello_world
函数,只需要输入以下代码:
hello_world()
运行后,就会输出“Hello World!”。
3.1 调用带参数的函数
当定义函数时,可以定义参数。这些参数可以传递给函数并在函数内部使用。
def square(x):
return x * x
在这个函数中,我们定义了一个参数x
,它的值可以是任意整数或浮点数。 要使用这个函数,我们可以将值传递给它:
print(square(5))
运行后,输出25。这个函数接收一个参数5
作为输入值,并返回25作为结果。
3.2 函数的返回值
函数返回值是函数通过执行操作后返回的值。在使用函数时,我们可以使用return
语句返回一个值。函数可以在任何地方返回一个值,不仅仅只有在函数的结尾。
例如:
def cube(x):
return x * x * x
print(cube(3))
这个函数计算输入值x
的立方,使用return
语句返回结果。然后,我们通过调用这个函数,并传递值3
作为参数,输出返回的结果:
27
如果函数没有明确地通过return
语句返回一个值,则它返回特殊的变量值None
。
4. 匿名函数和lambda表达式
4.1 匿名函数
Python中的一个很有趣的特性是:允许定义一个不使用def
关键字的函数,称之为匿名函数。匿名函数的作用是只在使用时才进行定义,这种定义方式因为没有命名的原因,称之为匿名函数。
Python通过lambda
关键字来定义匿名函数。
最简单的函数是一个没有参数的lambda表达式:
lambda: True
上面这个例子中我们定义了一个没有参数的lambda表达式,它的返回值为True
。
4.2 lambda表达式的语法
lambda表达式具有以下形式:
lambda arguments: expression
lambda具有以下特征:
lambda关键字表示定义匿名函数。
arguments表示参数,多个参数使用逗号隔开。
expression表示要求值的Python表达式。
例如,下面的代码定义了一个lambda
表达式,它接受一个参数x
,并返回它的平方:
square = lambda x: x * x
print(square(5))
这个匿名函数首先定义一个变量square
,并将其赋值为lambda
表达式。该表达式接受一个参数x
,并返回x
的平方。然后,使用这个匿名函数,我们通过调用函数square(5)
来输出输入值5
的平方。
5. 函数参数的默认值
函数参数可以有一个默认值,如果不提供该参数的值,函数会使用默认值。
def print_hello(name='world'):
print('Hello, ' + name + '!')
print_hello()
上面这个函数有一个参数,参数的默认值为'world'
。 调用这个函数时,即使没有传递参数,也不会报错。函数会使用默认参数'world'
,然后输出“Hello, world!”。
6. 函数的可变参数
Python中可以定义参数数量可变的函数,可以用于传递可变的参数。在函数定义中,使用*args
表示参数数量可变,这里的args
是一个tuple类型的变量名。
def print_things(*things):
for thing in things:
print(thing)
print_things('apple', 'banana', 'cherry')
上面这个函数接受可变数量的参数,使用for
循环遍历所有参数并将它们打印出来。 调用函数print_things('apple', 'banana', 'cherry')
将输出以下内容:
apple
banana
cherry
6.1 带有可变数量参数的函数定义
在带有可变数量参数的函数定义中,需要注意以下几点:
在处理不同类型的可变数量参数时,参数的类型可以使用不同的名称。
在参数列表中,可变数量参数必须放在参数的最后一个位置。在*args
后面不能再添加参数。
7. 函数的高级特性
7.1 在函数中嵌套函数
在Python中,可以在一个函数中嵌套另一个函数。
嵌套函数可以通过父函数的名称和参数来调用。
def parent_func(x):
def child_func(y):
return x * y
return child_func
double = parent_func(2)
print(double(5)) # 输出10
在这个例子中,我们定义了一个父函数parent_func
和一个嵌套的子函数child_func
。子函数在父函数中定义,然后将其返回。parent_func
函数的返回值是子函数child_func
的名称。double = parent_func(2)
创建一个新的函数double
,它是子函数child_func
在父函数parent_func
中的调用结果。最后,我们调用函数double(5)
来输出结果。
7.2 装饰器
装饰器是Python中非常重要的特性之一。它可以用于将一个函数包装在另一个函数之内,以增强函数的功能。这种用法被称为装饰器模式。
7.2.1 装饰器的基本使用
假设我们想要在函数的执行前后记录函数的运行时间,此时就可以使用装饰器。
下面是一个简单的示例:
import time
def time_it(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print('Function {} took {:f} seconds'.format(
func.__name__, end - start))
return result
return wrapper
@time_it
def my_function():
time.sleep(1)
my_function()
这个装饰器函数time_it
接受一个函数作为参数,并返回一个新函数wrapper
。这个新函数会在调用原始函数之前记录当前时间,调用之后再次记录时间并计算执行时间。
使用装饰器,代码更加简洁。使用@decorator_name
就可以对函数进行装饰,这与我们刚才的示例中直接将函数传递给装饰器函数是等价的。这也是Python中装饰器的一大优势。
7.2.2 多个装饰器的使用
当我们在Python中定义带有多个装饰器的函数时,Python的解释器会按顺序应用这些装饰器。
例如:
def my_logging_decorator(func):
def wrapper(*args, **kwargs):
print('LOG: Calling function: {}'.format(func.__name__))
return func(*args, **kwargs)
return wrapper
def my_timing_decorator(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print('TIMING: Function {} took {:f} seconds'.format(
func.__name__, end - start))
return result
return wrapper
@my_logging_decorator
@my_timing_decorator
def my_function(a, b):
time.sleep(1)
return a + b
my_function(1, 2)
这个示例定义了一个记录函数调用和执行时间的装饰器:my_logging_decorator
和my_timing_decorator
。在定义函数my_function
时,我们使用这两个装饰器,它们的顺序与它们在代码中的出现顺序是一致的。这意味着,首先将my_logging_decorator
应用到my_function
,然后再应用my_timing_decorator
。
7.3 生成器函数
Python中的生成器可以用于快速创建可迭代的对象,通常用于迭代需要大量资源的数据集。
Python中的生成器可以通过函数来实现,这样就可以自定义自己的生成器。
def even_numbers(start=0, end=10):
for i in range(start, end):
if i % 2 == 0:
yield i
for num in even_numbers():
print(num)
这个生成器函数even_numbers
接受两个参数start
和end
,并生成从start
到end
之间的所有偶数。
在函数内部,我们使用了for
循环遍历所有的数字,使用一个条件判断偶数。然后我们使用yield
来生成这个数字。
在使用生成器时,调用函数返回一个迭代器。使用for
循环遍历这个迭代器,原始函数中的yield
语句开始执行,它返回相应的值,然后运行函数的其余部分,直到下一个yield
语句被执行。 此过程会继续下去,直到函数到达其结尾或遇到一个return
语句。
虽然这个示例看起来很简单,但它可以解决许多大型数据集的内存问题。通过使用生成器函数,我们不需要将所有数据都存储在内存中,而是可以快速计算所有项并返回它们。
8. 总结
在本章中,我们介绍了Python中函数的基本操作,包括函数的定义、调用、默认参数、可变数量参数、生成器等。同时,还介绍了Python中高级函数,包括嵌套函数、装饰器等。
......