面试题答案
一键面试类方法场景
优化思路:在类方法中,可以通过对传入的列表进行拷贝,然后在方法内使用拷贝后的列表,这样就不会修改原始列表。 代码示例:
class MyClass:
@classmethod
def my_class_method(cls, my_list):
new_list = my_list.copy()
# 对new_list进行操作,不会影响原始my_list
new_list.append(1)
return new_list
original_list = [1, 2, 3]
result = MyClass.my_class_method(original_list)
print(original_list) # 输出: [1, 2, 3]
print(result) # 输出: [1, 2, 3, 1]
多线程环境场景
优化思路:使用threading.Lock
来保证在任何时刻只有一个线程可以访问和修改列表。同时可以将列表封装在一个类中,通过类的方法来操作列表,在方法内加锁。
代码示例:
import threading
class SafeList:
def __init__(self, initial_list):
self.list = initial_list
self.lock = threading.Lock()
def append(self, value):
with self.lock:
new_list = self.list.copy()
new_list.append(value)
self.list = new_list
def get_list(self):
with self.lock:
return self.list.copy()
safe_list = SafeList([1, 2, 3])
def thread_function():
safe_list.append(4)
threads = []
for _ in range(5):
t = threading.Thread(target=thread_function)
threads.append(t)
t.start()
for t in threads:
t.join()
print(safe_list.get_list()) # 输出: [1, 2, 3, 4, 4, 4, 4, 4]
函数装饰器场景
优化思路:装饰器可以在函数调用前后进行处理,在函数调用前对列表进行拷贝,将拷贝后的列表传递给函数,函数返回后再对比是否有修改,如果有修改则抛出异常或者采取其他处理。 代码示例:
def protect_list(func):
def wrapper(*args, **kwargs):
new_args = []
for arg in args:
if isinstance(arg, list):
new_args.append(arg.copy())
else:
new_args.append(arg)
new_kwargs = {}
for key, value in kwargs.items():
if isinstance(value, list):
new_kwargs[key] = value.copy()
else:
new_kwargs[key] = value
result = func(*new_args, **new_kwargs)
return result
return wrapper
@protect_list
def my_function(my_list):
my_list.append(1)
return my_list
original_list = [1, 2, 3]
result = my_function(original_list)
print(original_list) # 输出: [1, 2, 3]
print(result) # 输出: [1, 2, 3, 1]