Python高级函数:掌握闭包和装饰器的使用方法
一、什么是闭包?
在Python中,闭包(Closure)是指一种特殊的对象。闭包由两个部分组成:代码块和环境。代码块是一个函数,环境是代码块中的非全局变量的值集合。
二、闭包的定义
在Python中,一个变量的作用域(Scope)是指在什么范围内能够访问这个变量。如果变量在函数内定义,它的作用域就是这个函数的内部,如果变量在函数外定义,它的作用域是整个脚本。
如果在函数内部定义一个函数,且该内部函数引用了函数外部的变量,就会形成闭包。
如下例:
def outer_func():
message = 'Hi'
def inner_func():
print(message)
return inner_func
my_func = outer_func()
my_func() # Output: Hi
说明:outer_func() 函数返回了 inner_func 函数,inner_func 函数引用了 outer_func() 函数中的 message 变量,因此 inner_func 函数就是一个闭包。
闭包的特点:
1、闭包能够访问它定义时在其上层函数的名称空间中的变量
2、即使其定义的函数已经被删除或已经离开了其名称空间,闭包仍然能够访问这些变量
三、解释装饰器
装饰器(Decorator)是 Python 中非常重要的一个概念。它可以改变一个函数的行为,而无需修改函数的代码。我们可以把装饰器理解为把某种变形进行系统化操作的过程。在Python中,装饰器的实现基于闭包。
Python 中的装饰器通常使用 @ 符号表示,它是最快捷的方式。如果要使用装饰器可以在函数定义前直接使用 @ 符号进行装饰,示例如下:
def decorator(func):
def inner():
print("Hello World")
func()
return inner
@decorator
def original_func():
print("This is original function")
original_func()
说明:
1、使用 @decorator 对函数 original_func 进行修饰
2、decorator 函数返回了 inner 函数,inner 函数在 print("Hello World") 以及调用原始函数之前输出 "Hello World"
3、在函数调用时,现在可以使用装饰器 "在运行时(runtime)修改函数或者方法的功能",看起来是个很酷的功能。
4、在上述示例代码中,def original_func() 是直接调用 inner() 函数,相当于 inner() 作为了 original_func() 的替身而存在,输出结果为:
Hello World This is original function
三、闭包与装饰器的应用
1、函数嵌套
前面已经讲过,闭包是 Python 中函数嵌套的结果,这是大括号在 Python 语法中的重要应用。例如,你可能经常看到在类中的函数嵌套,通过这种方式来封装类内的私有函数。
2、管道简化计算过程
管道就像 Unix 系统中的管道一样,读取一个数据,在对其进行操作之前可以将其通过多个函数传递。如果没有闭包和装饰器,这将非常麻烦,但如果使用装饰器编写,就可以轻松地将其转换为管道处理。以下是一个简化的计算示例:
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
return a / b
def apply(func, x, y):
return func(x, y)
print(apply(add, 5, 2)) # Output: 7
print(apply(subtract, 5, 2)) # Output: 3
print(apply(multiply, 5, 2)) # Output: 10
print(apply(divide, 5, 2)) # Output: 2.5
在代码运行中,能在几个函数之间进行切换,以执行所需的计算。
3、使用装饰器创建单例模式
单例模式(Singleton pattern) 是一个创建对象的设计模式,其目的是,禁止用户重复创建对象。在 Python 中,单例模式创建起来很简单,以下是一个示例:
def singleton(cls):
instances = {}
def get_instance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return get_instance
@singleton
class MyClass:
pass
obj1 = MyClass()
obj2 = MyClass()
print(obj1 == obj2) # Output: True
说明:
1、在上述代码中,定义了一个函数 singleton ,该函数使用字典实现单例模式
2、使用 @singleton 装饰器对 MyClass 进行装饰,为其创建了一个单一实例
3、使用 obj1 = MyClass() 语句实例化 MyClass 类,再使用 obj2 = MyClass() 实例化 MyClass 类,最后输出 obj1 和 obj2,判断它们的值是否相等,得到 True。
四、总结
闭包和装饰器是 Python 编程中很常用的特性,它们的强大功能可以简化编程过程,还可以优化函数和程序的性能。在程序设计中,一个 Python 开发人员需要了解闭包和装饰器,并且要学会高效使用他们才能写出优秀的 Python 代码。
