python闭包、深浅拷贝、垃圾回收、with语句知识点

1、python闭包

Python闭包是一种函数式编程的实现方式。简单来说,闭包指的是一个函数对象可以访问其词法作用域中的变量,即便是在该函数在词法作用域外被调用时。闭包在Python中的应用十分广泛。比如,可以使用闭包在函数外部缓存变量或状态值,在多线程编程中避免出现竞争条件等等。

闭包的实现依赖于Python的函数对象特性。在Python中,函数本身是一种对象,可以像其他对象一样被引用或传递给其他函数。因此,可以将一个内部函数的引用作为参数传递给外部函数,这样就构成了最简单的闭包。

闭包的简单实现

下面是一个简单的闭包实现示例,其中外部函数返回内部函数的引用:

def outer_function(x):

def inner_function(y):

return x + y

return inner_function

closure = outer_function(10)

result = closure(5)

print(result) # 输出15

在上面的代码中,outer_function 返回 inner_function 的引用,可以将其保存在变量 closure 中。之后,闭包通过 closure(5) 调用了 inner_function,并返回了其计算结果 15。

由于闭包可以访问外部函数的变量,在某些情况下需要特别注意变量作用域。比如,下面的示例展示了一个错误的闭包实现,会导致所有的回调函数打印的值都相同:

def outer_function():

callbacks = []

for i in range(5):

callbacks.append(lambda : i)

return callbacks

callbacks = outer_function()

for c in callbacks:

print(c())

上述代码输出的结果都是 4,这是因为所有的回调函数都引用了同一个 i 变量,而该变量在循环结束后被赋值为 4。为了避免这种问题,可以使用闭包来捕获循环迭代变量:

def outer_function():

callbacks = []

for i in range(5):

callbacks.append(lambda x=i: x)

return callbacks

callbacks = outer_function()

for c in callbacks:

print(c())

在上述代码中,将循环迭代变量 i 作为默认参数传递给了 lambda 表达式,从而实现了闭包。现在,每个回调函数都捕获了不同的 i 值,并正确地将其打印出来。

2、深浅拷贝

Python中的拷贝分为两种方式:浅拷贝和深拷贝。浅拷贝只是拷贝了原对象中的引用,而不是对象本身,而深拷贝则是对原对象进行了递归拷贝,生成与原对象结构相同的新对象。

浅拷贝的示例

下面的示例展示了如何使用浅拷贝复制一个列表:

list1 = [[1, 2], [3, 4]]

list2 = list1.copy()

print(list1 == list2) # True

print(list1 is list2) # False

list1[0][0] = 0

print(list1) # [[0, 2], [3, 4]]

print(list2) # [[0, 2], [3, 4]]

在上面的代码中,使用 list1.copy() 方法生成了一个新的列表 list2。修改 list1 中嵌套的列表的值后,发现 list2 中对应的值也被修改了。

深拷贝的示例

下面的示例展示了如何使用深拷贝对一个列表进行复制:

import copy

list1 = [[1, 2], [3, 4]]

list2 = copy.deepcopy(list1)

print(list1 == list2) # True

print(list1 is list2) # False

list1[0][0] = 0

print(list1) # [[0, 2], [3, 4]]

print(list2) # [[1, 2], [3, 4]]

在上面的代码中,使用 copy.deepcopy 方法对 list1 进行了深度拷贝。通过对 list1 中嵌套的列表的值进行修改后,发现 list2 中对应的值并没有发生变化。

3、垃圾回收

Python 采用了自动垃圾回收机制,可以自动检测并且释放不再使用的内存,使开发者更加专注于业务逻辑的实现。Python的垃圾回收机制主要使用了引用计数。

引用计数的工作原理

引用计数是指Python内部维护的一个计数器,用于统计一个对象的引用计数(即有多少个变量指向该对象)。当该计数器减少到0后,Python会自动回收该对象占用的内存空间。

在Python中,每个对象都有一个指针,用于指向其他对象。每当一个对象被赋值给一个变量时,该变量就会增加该对象的引用计数;当变量被销毁或者重新赋值时,对应的对象的引用计数就会减少。如果一个对象的引用计数为0,那么被引用的对象占用的内存就会立即被释放。

引用计数的局限性

引用计数虽然是一种简单而有效的垃圾回收机制,但是它也存在一些局限性:

循环引用,即两个或多个对象之间相互引用,导致它们的引用计数一直不为0,从而无法被回收。

多线程情况下,引用计数的操作不是线程安全的,可能会发生意料之外的行为。

4、with语句

Python 中的 with 语句提供了一个简洁的语法,可以让我们轻松地管理资源。使用 with 语句可以有效地避免资源泄漏和错误处理等问题。

with 语句的语法

with 语句与 try/finally 语句类似,但是相比于 try/finally 语句,with 语句的语法更加简洁易懂。使用 with 语句的一般形式如下:

with expression [as variable]:

with-block

其中,expression 表示一个需要进行上下文管理的对象,with-block 是由语句或语句块组成的代码段。在这个代码段中,可以使用 expression 表达式所代表的对象。

如果指定了 as variable,那么该表达式的值会被赋给 variable,方便我们在 with-block 中使用。with 语句执行完毕后,会自动调用 expression.__exit__() 方法,释放资源。

with 语句的示例

下面的示例展示了如何使用 with 语句来打开一个文件,并读取其中的内容:

with open('data.txt', 'r') as file:

content = file.read()

print(content)

在上述代码中,使用 with 语句打开一个文件,并将其赋给变量 file。之后,在 with 代码块中,读取了文件的内容,并将其赋给 content 变量。在 with 语句执行完毕后,会自动关闭该文件。

总结

本文介绍了Python闭包、深浅拷贝,垃圾回收以及with语句等一些常用的Python编程技巧。这些技巧可以帮助我们更加高效地实现业务逻辑,并且提高代码的可读性和健壮性。在编写Python程序的过程中,我们应该灵活运用这些技巧,根据实际情况选用最合适的方案。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。

后端开发标签