1.python的装饰器怎么理解?举例说明应用场景
Python 的装饰器是一种设计模式,用于修改或增强函数或方法的行为,而无需改变其定义。
装饰器本质上是一个函数,它接收一个函数作为参数,并返回一个新的函数。
理解装饰器
装饰器通过包装原始函数来实现功能增强,而不需要修改原始函数的代码。这使得代码更加模块化,易于维护和扩展。装饰器通常用于日志记录、性能测试、事务处理、缓存、权限校验等场景
应用场景举例
-
日志记录:在函数执行前后添加日志记录,帮助跟踪函数的调用和执行情况。
def log_decorator(func): def wrapper(*args, **kwargs): print(f"Calling {func.__name__}...") result = func(*args, **kwargs) print(f"{func.__name__} executed.") return result return wrapper @log_decorator def add(a, b): return a + b add(2, 3)
-
权限控制:在函数执行前检查用户权限,确保只有具备相应权限的用户才能执行某些操作。
def admin_required(func): def wrapper(*args, **kwargs): if not user.is_admin: raise Exception("Access Denied") return func(*args, **kwargs) return wrapper @admin_required def delete_user(user_id): # 删除用户逻辑 pass
性能测试:在函数执行前后记录时间,用于性能分析。
import time
def time_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} took {end_time - start_time} seconds to execute.")
return result
return wrapper @time_decorator
def compute_large_number(): # 计算大数逻辑
pass
2.简单描述下python的垃圾回收机制
-
Python 的垃圾回收机制主要依赖于引用计数(reference counting)和分代收集(generational collection)两种策略。
-
引用计数:Python 为每个对象维护一个引用计数器,每当有新的引用指向该对象时,计数器增加;当引用被删除时,计数器减少。当某个对象的引用计数降为0时,意味着没有任何引用指向该对象,该对象可以被垃圾回收器回收。
-
分代收集:Python 将对象分为三代(0, 1, 2)。新创建的对象属于第0代,当对象在一次垃圾回收后仍然存活,则晋升到第1代,以此类推。垃圾回收器会优先回收年轻代(0代和1代)的对象,因为这些对象更有可能成为垃圾。当年轻代的回收不再有效时,才会对老年代(2代)进行回收。
-
垃圾回收器:Python 还提供了一个可选的垃圾回收器(gc模块),可以手动触发垃圾回收,或者设置回收的阈值等。这种机制有效地管理内存使用,避免了内存泄漏,但也可能带来一定的性能开销。
3.python 实现斐波那契数列并输出结果。
编写一个程序,实现斐波那契数列并输出结果。
要求如下:
-
数列长度通过用户输入获取;
-
输出结果需要以列表形式展示。
提示:斐波那契数列是一个无限长的数列,从第三项开始每一项都等于前两项之和。即 F(n) = F(n-1) + F(n-2),其中 F(0) = 0,F(1) = 1。
def fibonacci(n):
# 初始化斐波那契数列的前两项
fib_sequence = [0, 1]
# 如果用户输入的数列长度小于等于0,直接返回空列表
if n <= 0:
return []
# 如果用户输入的数列长度为1,返回只包含第一个元素的列表
elif n == 1:
return [0]
# 生成斐波那契数列
for i in range(2, n):
next_value = fib_sequence[-1] + fib_sequence[-2]
fib_sequence.append(next_value)
return fib_sequence
# 用户输入数列长度
n = int(input("请输入斐波那契数列的长度:"))
# 调用函数并打印结果
print(fibonacci(n))
4.二分查找有序数列中的值的位置
输入一个包含11的有序数组,请用二分查找法,找到11所在的数组下标
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid # 找到目标值,返回其索引
elif arr[mid] < target:
left = mid + 1 # 在右半部分继续查找
else:
right = mid - 1 # 在左半部分继续查找
return -1 # 如果没有找到目标值,返回-1
# 有序数组
arr = [1, 2, 3, 5, 8, 11, 14, 17, 23, 31, 45]
# 要查找的目标值
target = 11
# 调用二分查找函数
index = binary_search(arr, target)
# 输出结果
if index != -1:
print(f"元素 {target} 在数组中的下标为 {index}")
else:
print(f"数组中不存在元素 {target}")
5.输出重复数字
将给定int 数组的重复数字输出出来
def find_duplicates(arr):
seen = set()
duplicates = set()
for num in arr:
if num in seen:
duplicates.add(num)
else:
seen.add(num)
return duplicates
# 示例数组
arr = [1, 2, 3, 4, 5, 2, 3, 6, 7, 8, 9, 10, 11, 12, 2]
# 调用函数查找重复数字
duplicates = find_duplicates(arr)
# 输出结果
if duplicates:
print("数组中的重复数字有:", duplicates)
else:
print("数组中没有重复数字。")
6.找到数列中最接近平均值的数
def closest_to_average(arr):
if not arr:
return None # 如果数组为空,返回 None
average = sum(arr) / len(arr) # 计算平均值
closest = arr[0] # 假设第一个数是最接近的
min_diff = abs(average - arr[0]) # 计算第一个数与平均值的差的绝对值
for num in arr:
diff = abs(average - num) # 计算当前数与平均值的差的绝对值
if diff < min_diff:
min_diff = diff
closest = num # 更新最接近的数
return closest
# 示例数组
arr = [1, 2, 3, 4, 5, 6]
# 调用函数找到最接近平均值的数
result = closest_to_average(arr)
# 输出结果
if result is not None:
print(f"最接近平均值的数是:{result}")
else:
print("数组为空,无法找到最接近平均值的数。")
7.python实现快速排序
输入一串数字,对数字进行快速排序,并以数组的形式输出
def quick_sort(arr):
if len(arr) <= 1:
return arr
else:
pivot = arr[0] # 选择第一个元素作为基准
less = [x for x in arr[1:] if x <= pivot] # 所有小于等于基准的元素
greater = [x for x in arr[1:] if x > pivot] # 所有大于基准的元素
return quick_sort(less) + [pivot] + quick_sort(greater) # 递归排序并合并
# 输入一串数字
input_numbers = input("请输入一串数字,用空格分隔:")
# 将输入的字符串转换为整数数组
numbers = list(map(int, input_numbers.split()))
# 调用快速排序函数
sorted_numbers = quick_sort(numbers)
# 输出排序后的数组
print("排序后的数组:", sorted_numbers)