面试题答案
一键面试1. 文件操作场景
- 实际应用:在读取或写入文件时,使用
__enter__
和__exit__
方法可以确保文件在使用完毕后正确关闭,避免资源泄漏。 - 作用机制:
- 当使用
with open('file.txt', 'r') as f
语句时,open
函数返回的对象具有__enter__
和__exit__
方法。__enter__
方法在进入with
代码块时被调用,它返回的对象会赋值给as
关键字后的变量(这里是f
),一般在这个方法中进行资源的初始化,比如打开文件。 - 当离开
with
代码块时,无论代码块内是否发生异常,__exit__
方法都会被调用。在文件操作场景中,它负责关闭文件,释放系统资源。例如:
- 当使用
with open('test.txt', 'w') as file:
file.write('Hello, World!')
这里,file
对象的__enter__
方法打开文件,__exit__
方法在代码块结束时关闭文件。
2. 数据库连接场景
- 实际应用:在与数据库进行交互时,通过
__enter__
和__exit__
方法来管理数据库连接的生命周期,确保连接在使用完后被正确关闭,并处理可能发生的事务。 - 作用机制:
- 假设使用
sqlite3
库连接SQLite数据库,__enter__
方法用于建立数据库连接,例如conn = sqlite3.connect('example.db')
,并返回连接对象。 - 在
with
代码块内执行数据库操作,如创建表、插入数据等。 __exit__
方法在离开with
代码块时被调用。如果代码块内没有异常,__exit__
方法会提交事务;如果发生异常,__exit__
方法会回滚事务,并关闭数据库连接。示例代码如下:
- 假设使用
import sqlite3
with sqlite3.connect('example.db') as conn:
cursor = conn.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)')
cursor.execute('INSERT INTO users (name) VALUES ("John")')
这里conn
对象的__enter__
方法建立数据库连接,__exit__
方法根据是否有异常来提交或回滚事务并关闭连接。
3. 锁操作场景(多线程环境)
- 实际应用:在多线程编程中,使用锁来防止多个线程同时访问共享资源,避免数据竞争和不一致问题。
__enter__
和__exit__
方法可用于管理锁的获取和释放。 - 作用机制:
- 以
threading.Lock
为例,__enter__
方法获取锁,确保当前线程获得对共享资源的访问权限。例如lock = threading.Lock()
,在with lock
语句中,lock
对象的__enter__
方法获取锁。 - 在
with
代码块内,线程可以安全地访问共享资源。 __exit__
方法在离开with
代码块时释放锁,允许其他线程获取锁并访问共享资源。示例代码:
- 以
import threading
lock = threading.Lock()
shared_variable = 0
def increment():
global shared_variable
with lock:
shared_variable += 1
threads = []
for _ in range(10):
t = threading.Thread(target = increment)
threads.append(t)
t.start()
for t in threads:
t.join()
print(shared_variable)
这里lock
对象的__enter__
方法获取锁,__exit__
方法释放锁,保证了shared_variable
在多线程环境下的安全访问。