第三周周测
第三周周测
1.函数参数的两⼤⼤分类及两者关系
- 分类
- 形参
- 形式参数是在函数定义时声明的变量,用于接收调用该函数时传入的实际参数的值
- 实参
- 实际参数是在函数调用时传递给函数的具体数值或变量。
- 形参
- 关系
- 当函数被调用时,实际参数的值会被赋值给相应的形式参数,然后函数使用这些形式参数进行计算和操作。
2.阐述函数参数的种类及各⾃特征
- 函数参数的种类
-
默认参数
- 在函数定义时指定默认值的参数,如果函数调用时没有传入该参数,将使用默认值。
- 默认参数必须在位置参数后面定义,否则会产生语法错误。
-
关键字参数
- 使用形如“key=value”的语法来指定参数,可以不按照定义顺序传递参数。
- 如果一个函数同时接收位置和关键字参数,位置参数必须在关键字参数之前传递。
-
位置参数
- 按照定义顺序传递给函数的参数,是最常见的参数类型。
- 函数调用时必须提供该参数,否则会抛出异常。
-
*args- 使用星号(*)作为前缀,在函数定义时接受任意数量的位置参数,以元组的形式传递给函数。
- 调用时可以传递任意数量的位置参数。
-
**kwargs- 使用两个星号(**)作为前缀,在函数定义时接受任意数量的关键字参数,以字典的形式传递给函数。
- 调用时可以传递任意数量的关键字参数。
-
3.什么是名称空间,有哪些种类,查找顺序如何确定
-
什么是名称空间
- 名称空间是一个用于存储变量名与具体对象之间关系的数据结构。
- 它允许在程序中使用相同名称但指向不同对象的变量。
-
分类
- 全局名称空间(global namespace)
- 包含程序中定义的全局变量和函数的名称。
- 内置名称空间(built-in namespace)
- 包含所有内置函数和异常的名称。
- 本地名称空间(local namespace)
- 在函数调用时创建,包含函数参数和在函数内部定义的局部变量。
- 全局名称空间(global namespace)
-
查找顺序
- 由 LEGB 规则决定,即从当前作用域开始依次向上查找,直到找到第一个匹配的名称为止。
- LEGB 是指 Local、Enclosing、Global 和 Built-in 四个作用域,按照这个顺序逐级往上搜索,直到找到符合条件的变量或者抵达最外层作用域。
4.关键字global与nonlocal的作⽤
-
global
- 用于在函数内部访问并修改全局变量,即在函数内部将一个变量声明为 global 后,对该变量的修改将影响到全局作用域中的变量。
x = 1 def func(): global x x = 2 func() print(x) # 输出 2 -
nonlocal
- 用于在嵌套函数中访问并修改外层函数的变量,即在内层函数中将一个变量声明为 nonlocal 后,对该变量的修改将影响到外层函数作用域中的变量。
def outer(): x = 1 def inner(): nonlocal x x = 2 inner() print(x) # 输出 2 outer()
5.函数名的使⽤⽅法有哪些
- 函数名的使用方法
- 定义函数:
- 使用函数名来创建一个新的函数,指定函数的名称、输入参数和输出结果等信息,以便在程序中调用该函数。
- 调用函数:
- 使用函数名来调用已经定义好的函数,传递需要处理的输入参数,并获取函数返回的计算结果。
- 作为参数传递:
- 将函数名作为参数传递给另一个函数或方法,使得该函数或方法可以调用所传递的函数进行特定的计算操作。
- 作为返回值返回:
- 函数名也可以作为另一个函数的返回值返回,从而实现一些高级编程技巧,如函数式编程或装饰器模式。
- 作为对象属性访问:
- 在某些面向对象编程语言中,函数名也可以作为对象的属性之一,通过对象引用获取该函数并调用。
- 定义函数:
6.什么是闭包函数,有何实际应⽤
- 闭包函数
- 指在函数内部定义的函数,它可以访问和修改其外部函数的变量,并且在外部函数执行完毕后仍然可以保持对这些变量的引用。
- 实际应用
- 闭包函数通常用于需要记住状态或者保存上下文信息的场景中
- 例如
- 事件处理器
- 回调函数等。
7.什么是装饰器,你能详细说说装饰器的推导流程吗
-
什么是装饰器
- 在不修改函数源代码的情况下,动态的增强或者修改函数的行为。
-
推导流程
- 定义一个装饰器函数,该函数接收一个函数作为参数,并返回一个新的函数。
- 在新的函数中使用原始函数并添加额外的逻辑。
- 将新的函数返回作为原始函数的替代品。
def my_decorator(func): def wrapper(): print("Starting the function...") func() print("Function completed.") return wrapper @my_decorator def my_function(): print("Hello, world!") my_function()- 这个装饰器定义了一个名为
my_decorator的函数,它接收一个函数作为参数。 - 在函数内部,它定义了一个新的函数
wrapper,该函数在调用原始函数之前和之后输出一些信息。 - 最后,装饰器返回
wrapper函数,并通过@my_decorator这个语法糖来应用装饰器到my_function上。 - 运行
my_function()时,将会依次输出 "Starting the function..."、"Hello, world!" 和 "Function completed."。
8.⼿写装饰器模板(普通+修复+有参)
-
普通装饰器
def decorator(func): def wrapper(*args, **kwargs): # 对函数进行装饰 return func(*args, **kwargs) return wrapper @decorator def my_function(): pass -
修复技术
from functools import wraps def decorator(func): @wraps(func) def wrapper(*args, **kwargs): # 对函数进行装饰 return func(*args, **kwargs) return wrapper @decorator def my_function(): pass -
有参装饰器
def decorator_with_args(arg1, arg2): def decorator(func): def wrapper(*args, **kwargs): # 对函数进行装饰,使用arg1和arg2 return func(*args, **kwargs) return wrapper return decorator @decorator_with_args(arg1, arg2) def my_function(): pass
9.装饰器语法糖作⽤机理
- 什么是装饰器语法糖
- 装饰器语法糖是一种Python编程语言特性
- 它允许开发者在不修改原始函数代码的情况下
- 通过在函数定义之前加上一个修饰器函数
- 改变函数的行为或添加额外的功能。
- 当一个函数被修饰器修饰后,在调用该函数时
- 实际上是调用了修饰器返回的新函数。
- 这个新函数可以包装原始函数,添加额外的逻辑或修改输入和输出等行为。
- 装饰器使得代码更加简洁,易于维护和重用。
- 装饰器语法糖是一种Python编程语言特性
- 装饰器语法糖的作用机理
-
基于Python中函数也是对象的概念。
- 因为函数本质上是对象
- 所以可以将一个函数作为参数传递给另一个函数
- 并在另一个函数内对其进行修改或包装
- 最后返回修改后的函数。
-
这种使用函数作为参数并返回函数的编程技巧称为高阶函数。
-
装饰器利用了高阶函数的思想,使得开发者能够更加方便地对函数进行扩展和修改。
-
10.什么是递归函数,python默认最⼤递归深度
-
什么是递归函数
- 递归函数是调用自身的函数。
-
在Python中,当一个函数调用自身时就会产生递归。
- Python默认的最大递归深度为1000
- 在达到这个深度之后,程序会抛出RecursionError异常。
- 可以使用sys模块中的setrecursionlimit()方法来增加最大递归深度
- 但需要注意过多地增加深度可能会导致程序栈溢出或其他问题。
- Python默认的最大递归深度为1000
11.⼿写出⼆分法伪代码
1. 将数组按升序排列
2. 定义变量 left = 0 和 right = 数组长度 - 1
3. 当 left <= right 时,执行以下步骤:
a. 将中间元素的下标 mid = (left + right) / 2 取整
b. 如果目标值等于数组中的中间元素,则返回 mid
c. 如果目标值小于中间元素,则将 right 更新为 mid - 1
d. 如果目标值大于中间元素,则将 left 更新为 mid + 1
4. 目标值不存在于数组中,返回 -1
def half_sort(l, search_num):
l.sort()
num = round(len(l) / 2)
if len(l) == 1:
print(l[0])
else:
if search_num in l[:num]:
l_left = l[0:num]
print(l_left)
half_sort(l_left, search_num)
else:
l_right = l[num:]
print(l_right)
half_sort(l_right, search_num)
12.什么是匿名函数,主要配置哪些函数⼀起使⽤,各⾃有何特征
-
什么是匿名函数
- 匿名函数是一种没有名称的函数,通常在需要临时定义和执行某些逻辑的情况下使用。
- 主要配置与之搭配使用的函数有高阶函数和Lambda函数。
lambda x:x*2 lambda 返回值:函数表达式 -
主要配置的函数
-
map
- 映射函数
- map(参数,匿名函数)
numbers = [1, 2, 3, 4, 5] squared_numbers = list(map(lambda x: x**2, numbers)) print(squared_numbers) # [1, 4, 9, 16, 25] -
filter
- 过滤函数,过滤条件为True的变量
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 过滤出所有偶数 even_numbers = list(filter(lambda x: x % 2 == 0, numbers)) print(even_numbers) # 输出:[2, 4, 6, 8, 10]
-
-
匿名函数的特征
- 没有名称,只能通过变量引用或作为参数传递使用。
- 可以有多个参数,但通常只包含一个表达式。
- 通常用于简单的逻辑,例如过滤列表或映射元素。
13.什么是可迭代对象、迭代器对象,两者有何关系
- 什么是可迭代对象
- 可迭代对象就是具有
__iter__()方法的对象 - 可迭代对象是指可以使用for循环遍历的对象,例如列表、元组、字典、集合等。
- 可迭代对象就是具有
- 迭代器对象
- 迭代器对象就是具有
__iter__()和__next__()方法的对象 - 迭代器对象
- 是指可以按照一定顺序逐个访问元素的对象
- 通过调用其 next() 方法来实现。
- 每次调用 next() 方法时,迭代器会返回下一个元素
- 当没有元素可以返回时,会抛出 StopIteration 异常。
- 通常情况下,一个可迭代对象能够产生一个迭代器对象。
- 迭代器对象就是具有
- 关系
- 迭代器对象一定是可迭代对象,可迭代对象不一定是迭代器对象
- 所有迭代器对象都是可迭代对象,但并非所有可迭代对象都是迭代器对象。
- 可迭代对象只有在被for循环或者手动转化成迭代器对象后才能逐个访问元素。
14.什么是异常、程序中如何解决异常、异常处理的完整结构是怎样的
-
什么是异常
- 异常是程序执行时出现的错误或意外情况
-
程序中如何解决异常
- 利用 try .. except .. 方法 捕获异常并抛出异常
-
异常处理的完整结构
try: print() except Exception as e: print("Error: " + str(e))- 可以配合else使用
- 发生错误则继续走else
try: print('111') except Exception as e: print("Error: " + str(e)) else: print("222")- 可以配合finally使用
- 发布发生错误都会走finally
try: print('111') except Exception as e: print("Error: " + str(e)) else: print("222") finally: print('333') - 可以配合else使用
【一】代码实战之装饰器计数
【1】需求
'''
1.编写统计函数执⾏次数装饰器
任意定义⼀个函数给其添加装饰器
要求:
每次执⾏该函数 装饰器⾃动记录次数 记录需保存在⽂件中
'''
【2】代码
# -*-coding: Utf-8 -*-
# @File : works_system .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/6/3
# 导入OS模块 ---> 用来创建文件,数据库位置
import os
# 装饰器修复技术所需要的模块 ---> 修复装饰器
from functools import wraps
# 定义装饰器函数 -- 外部函数
def func_counter(func):
# 声明数据库位置 ---> 存储到 txt 文件中
counts_file = 'func_counts.txt'
# 进行数据文件位置的判断 ---> 如果存在这个文件则忽略,如果不存在这个文件则新建
if not os.path.exists(counts_file):
# 创建文件并打开文件进行第一次写入 ---> 执行次数为1
with open(counts_file, 'w') as f:
f.write('1')
count = 1
else:
# 已经存在数据库位置文件 ---> 里面的数据至少为 1
# 打开数据库文件进行读取数据
with open(counts_file, 'r+') as f:
# 将拿到的数据(字符串数据) ---> 转为整型并 次数 +1
count = int(f.read()) + 1
# 将光标移动到首字符的位置,否则光标实在上一个字符的后边,造成字符追加的效果
f.seek(0)
# 写入数据(覆盖数据)
f.write(str(count))
# 定义装饰器内部函数
@wraps(func) # 装饰器的修复技术
def wrapper(*args, **kwargs):
# 这里拿到外部调用函数的返回值
result = func(*args, **kwargs)
# 返回这个调用函数的返回值
return result
# 统计一共运行了多少次
print(f'执行程序一共运行了::>>{count}次!')
# 返回内部的函数的内存地址
return wrapper
# 语法糖进行装饰
@func_counter
def my_function():
print('这是执行函数')
# 调用函数
my_function()
【二】代码实战之员工管理系统
【1】需求
2. 编写员⼯管理系统进阶版
功能全部封装成函数 数据全部来源于⽂件
⼤致功能:注册 登录 添加员⼯ 查看指定员⼯ 查看全体员⼯姓
名等
普通要求:
添加 查看等功能每次都必须先登录才可执⾏(认证装饰器)
进阶要求:
⽤户登录⼀次之后⽆⽆需校验身份(全局校验)
升华超越(选做题):
每个⽤户配备⻆⾊信息
⽤户认证过程中只有管理员才可执⾏被装饰函数
【2】代码
- 我的代码有一个小BUG,登录成功以后什么事没有
- 但是你不登陆,到添加员工信息就会飘红,然后退出~~~
- 我懒得改了,就这样吧
# -*-coding: Utf-8 -*-
# @File : 001 .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/6/3
import os
from functools import wraps
# 登录用户信息全局变量
login_user = None
# 角色信息全局变量,可以在读取角色信息的时候初始化
roles = {}
# 声明数据库位置
file_path_user_pwd = 'Information' + '\\' + 'user_pwd.txt'
file_path_user_roles = 'Information' + '\\' + 'user_roles.txt'
file_path_user_infos = 'Information' + '\\' + 'user_infos.txt'
# 创建数据库文件
def mkdir_db(file_path):
if not os.path.exists(file_path):
with open(file_path, 'a') as f:
if file_path == file_path_user_roles:
# dream:admin 默认管理员
data = 'dream:admin'
f.write(data + '\n')
elif file_path == file_path_user_pwd:
# 默认管理员密码 {username: password}
data = {'dream': '521521'}
f.write(str(data))
else:
f.write('')
# 调用函数创建数据库文件
mkdir_db(file_path_user_pwd)
mkdir_db(file_path_user_roles)
mkdir_db(file_path_user_infos)
# 存储用户名及密码
def write_user_pwd(username, user_pwd):
with open(file_path_user_pwd, 'a+') as f:
f.write(user_pwd)
print(f'{username}注册成功')
# 读取用户名及密码
def read_user_pwd():
user_info = []
with open(file_path_user_pwd, 'r+') as f:
for line in f:
user_pass_dict = {}
line = line.strip().split(':')
if len(line) == 2:
username, password = line[0], line[1]
user_pass_dict['username'] = username
user_pass_dict['password'] = password
user_info.append(user_pass_dict)
return user_info
# 读取用户详细信息
def read_work_info(cmd=1):
user_infos = []
# 读取员工信息
with open(file_path_user_infos, 'r+') as f:
# 2|2|2|2|2
for line in f:
user_info_details = {}
line = line.strip().split('|')
user_info_details['employee_id'] = line[0]
user_info_details['username'] = line[1]
user_info_details['age'] = line[2]
user_info_details['salary'] = line[3]
user_info_details['hobbies'] = line[4]
if cmd == 1:
user_infos.append(user_info_details)
elif cmd == 2:
print(f'用户用户名为:>>>>{line[1]}')
else:
print(f'''
当前用户ID为:>>>>{line[0]}
当前用户用户名为:>>>>{line[1]}
当前用户年龄为:>>>>{line[2]}
当前用户薪资为:>>>>{line[3]}
当前用户爱好为:>>>>{line[4]}
''')
return user_infos
# 写入用户详细信息
def write_work_info(username, data_info):
with open(file_path_user_infos, 'a') as f:
f.write(data_info)
print(f'username: %s 写入信息成功' % username)
# 写入角色信息
def write_work_roles(username, work_roles='normal'):
# police:meng
data = f'{username}:{work_roles}\n'
with open(file_path_user_roles, 'a') as f:
f.write(data)
# 读取角色信息
def load_roles():
with open(file_path_user_roles, 'r') as f:
for line in f:
# root:dream
role, users = line.strip().split(':')
# 'police': {'meng'}
roles[role] = set(users.split(','))
# 登录认证装饰器
def login_required(func_name):
@wraps(func_name)
def wrapper(*args, **kwargs):
# 全局修改登录的权限用户
global login_user
# 如果全局登录用户为空
if login_user is None:
# 全局用户为空则校验用户名和密码
# 输入用户名和密码
username = input('请输入你的用户名:>>>>')
password = input('请输入你的密码:>>>>')
# 进行用户名和密码的校对
# 从数据库拿到用户名及密码
user_info = read_user_pwd()
for i in user_info:
# 比较用户名信息及密码
if i['username'] == username and i['password'] == password:
# 登陆成功 打印登陆成功
print(f'{username}登陆成功!')
# 登陆成功并修改当前全局的登录信息
login_user = {'username': username, 'role': 'admin'}
return func_name(*args, **kwargs)
return wrapper
# 管理员身份认证装饰器
def admin_required(func_name):
@wraps(func_name)
def wrapper(*args, **kwargs):
if login_user['role'] == 'admin':
return func_name(*args, **kwargs)
else:
print(f'请使用管理员账号登录!')
return wrapper
# 注册新用户信息
def register_new():
username = input('Username')
password = input('Password')
user_pwd = f'{username}:{password}'
write_user_pwd(username, user_pwd)
# 注册用户默认携带 normal 正常用户属性
write_work_roles(username)
# 添加新员工
@login_required
@admin_required
def add_emplpoyee():
employee_id = input('请输入你的个人ID:>>>>')
username = input('请输入用户名:>>>>')
age = input('请输入年龄(必须是数字):>>>>')
salary = input('请输入薪资(必须是数字):>>>>')
hobbies = input('请输入爱好:>>>>')
# 存储的数据格式
data_info = f'{employee_id}|{username}|{age}|{salary}|{hobbies}\n'
# 调用写入信息函数进行写入信息
write_work_info(username, data_info)
# 查看指定员工信息
@login_required
def view_employee(employee_id):
# 从数据库拿到用户详细信息
user_infos = read_work_info()
for info in user_infos:
if employee_id == info['employee_id']:
ID = info['employee_id']
username = info['username']
age = info['age']
salary = info['salary']
hobbies = info['hobbies']
print(f'''
用户ID:>>>>{employee_id}
用户用户名:>>>>{username}
用户年龄:>>>>{age}
用户薪资:>>>>{salary}
用户爱好:>>>>{hobbies}
''')
# 查看所有员工姓名
@login_required
def list_employees():
read_work_info(2)
# 入口函数,根据用户输入调用相应功能
if __name__ == '__main__':
load_roles()
print(roles)
print(login_user)
while True:
print('1. 注册新用户')
print('2. 登录')
print('3. 查看指定员工信息')
print('4. 查看所有员工姓名')
print('5. 添加新员工')
print('6. 退出')
choice = input('请选择操作:')
if choice == '1':
register_new()
elif choice == '2':
login_required(lambda: None)() # 直接调用登录认证装饰器函数即可
elif choice == '3':
view_employee(input('请输入员工 ID:'))
elif choice == '4':
list_employees()
elif choice == '5':
add_emplpoyee()
elif choice == '6':
break
else:
print('无效的选项,请重新选择!')
本文来自博客园,作者:Chimengmeng,转载请注明原文链接:https://www.cnblogs.com/dream-ze/p/17455391.html

浙公网安备 33010602011771号