常见的内置函数、可迭代对象、迭代器对象、for循环内部原理
习题
有下列用户数据
user_data = {
'1': {'name': 'jason', 'pwd': '123', 'access': ['1', '2', '3']},
'2': {'name': 'kevin', 'pwd': '321', 'access': ['1', '2']},
'3': {'name': 'oscar', 'pwd': '222', 'access': ['1']}
}
并有三个函数
def func1():
pass
def func2():
pass
def func3():
pass
要求:调用上述三个函数的时候需要从user_data中校验用户身份是否正确
并获取当前登录用户拥有的可执行函数功能编号即键access对应的功能编号列表
func1是1、func2是2、func3是3
并且一旦用户登录成功之后后续函数的调用不再校验用户身份
请思考如何获取函数功能编号 如何校验用户身份 如何校验权限
ps:装饰器知识 附赠:实现上述主体功能即可 其他扩展优化功能可暂且不写
user_data = {
'1': {'name': 'jason', 'pwd': '123', 'access': ['1', '2', '3']},
'2': {'name': 'kevin', 'pwd': '321', 'access': ['1', '2']},
'3': {'name': 'oscar', 'pwd': '222', 'access': ['1']}
}
login_data = {
'is_login':False,
'user_access':[],
'user_name' :None
}
def login_auth(func_id):
def outer(func_name):
def inner(*args,**kwargs):
if login_data['is_login'] == True:
access = login_data['user_access']
user_name = login_data['user_name']
if func_id in access:
res = func_name(*args, **kwargs)
return res
else:
print(f"该用户{user_name}没有{func_id}的权限")
else:
user_id = input("请输入你的用户名编号>>>:").strip()
if user_id not in user_data:
print("没有这个人")
else:
user_name = input("请输入你的用户名>>>:").strip()
user_pwd = input("请输入你的密码:>>>").strip()
if user_name == user_data[user_id]['name'] and user_pwd == user_data[user_id]['pwd']:
access = user_data[user_id]['access']
login_data['is_login'] = True
login_data['user_access'] = access
login_data['user_name'] = user_name
if func_id in access:
res = func_name(*args,**kwargs)
return res
else:
print(f"该用户{user_name}没有{func_id}的权限")
return inner
return outer
@login_auth('1')
def func1():
print("from func1")
@login_auth('2')
def func2():
print("from func2")
@login_auth('3')
def func3():
print("from func3")
func1()
func2()
func3()
使用列表实现队列和堆栈的效果
队列:先进先出
堆栈:先进后出
队列
l1 = []
1.放数据
l1.append(1)
l1.append(2)
l1.append(3)
l1.append(4)
print(l1) # [1, 2, 3, 4]
2.取出数据
print(l1.pop(0)) # 1
print(l1.pop(0)) # 2
print(l1.pop(0)) # 3
print(l1.pop(0)) # 4
print(l1) # []
堆栈
l1 = []
1.放数据
l1.append(1)
l1.append(2)
l1.append(3)
l1.append(4)
print(l1) # [1, 2, 3, 4]
2.取数据
print(l1.pop()) # 4
print(l1.pop()) # 3
print(l1.pop()) # 2
print(l1.pop()) # 1
print(l1) # []
常见内置函数
内置函数是指提前定义好的,可以直接使用
1.abs() 求绝对值
eg:
print(abs(-1)) # 1
2.all() 与 any() 判断容器类型中所有数据值对应的布尔值是否为True
all() 容器类型中,所有值为真,才返回True(类似于and)
any() 容器类型中,只要有一个为真,就返回True(类似于or)
eg:
l1 = [1,2,3,4,0]
print(all(l1)) # False
print(any([1,2,3,4,0])) # True
3.bin() oct() hex() 将十进制数转换成二进制、八进制、十六进制
eg:
print(bin(100)) # 0b1100100 # 将十进制数转换成二进制
print(oct(100)) # 0o144 # 将十进制数转换成八进制
print(hex(100)) # 0x64 # 将十进制数转换成十六进制
4.int() 将其他进制数转换成十进制
eg:
print(int(0b1100100)) # 100
print(int(0o144)) # 100
print(int(0x64)) # 100
5.bytes() 将字符转换成二进制
str() 将任意类型转换成字符串
eg:
res = '你好,hello'
print(bytes(res,'utf8')) # b'\xe4\xbd\xa0\xe5\xa5\xbd\xef\xbc\x8chello'
res1 = bytes(res,'utf8')
print(str(res1,'utf8')) # 你好,hello
6.callable() 判断某个变量是否有调用的能力
eg:
def func():
pass
print(callable(func)) # True
name = 'nana'
print(callable(name)) # False
7.chr() 与 ord() 根据ASCII码表实现字符与数字的转换
chr() 将ASCII码表对应得数字转换为对应的字符
ord() 将ASCII码表对应得字符转换为对应的数字
eg:
print(chr(65)) # A
print(ord('A')) # 65
8.dir() 查看对象内所有的属性和方法
eg:
print(dir(list))
9.divmod() 获取除法之后的整数和余数
eg:
print(divmod(10,3)) # (3, 1)
10.enumerate() 枚举
eg:
list1= ['nana','xiao','lisa','linda']
for i in enumerate(list1,1):
print(i) # (1, 'nana') (2, 'xiao') (3, 'lisa') (4, 'linda')
for i,j in enumerate(list1): #默认是0开始
print(i,j) # 0 nana 1 xiao 2 lisa 3 linda
11.eval() 与 exec() 能够识别字符串中python代码并执行
eval() 只能识别最简单的代码,不能识别复杂的代码
exec() 能够识别复杂的代码
eg:
res1 = "print('nana')"
res2 = 'for i in range(10):print(i)'
eval(res1) # nana
eval(res2) # 报错
exec(res1) # nana
exec(res2) # 0 1 2 3 4 5 6 7 8 9
12.hash() # 获取一个对象(字符串或者数值等)的哈希值(返回一串随机的数字)
eg:
print(hash(12.2)) # 461168601842737164
print(hash('nana')) # 5609558760547864941
13.help() # 查看帮助信息
eg:
help(len)
14.isinstance() 判断某个数据是否属于某个数据类型
eg:
print(isinstance([1,2],list)) # True
print(isinstance([1,2],int)) # False
15.pow() 幂指数
eg:
print(pow(2,3)) # 8
16.round() 四舍五入 有时五舍六入
eg:
print(round(12,5)) # 12
print(round(12.4)) #12
迭代
迭代就是更新换代,每次迭代都需要基于上一次的成果
可迭代对象
1.如何判断是否是可迭代对象 >>> 通过句点符点出来有__iter__方法
1.1内置有__iter__方法的都叫做可迭代对象
1.2内置:通过句点符直接能够点出来的东西叫做内置
1.2__xxx__ 这对以双下划线开头双下划线结尾的方法 统一读作双下xxx
2.可迭代对象:字符串、列表、集合、元组、字典、文件(本身就是迭代器对象) >>>能够支持for循环取值
不可迭代对象:整型、浮点型、布尔值、函数名
迭代器对象
1.作用:迭代器对象给我们提供了一种不依赖于索引取值的方式,正是因为有迭代器对象的存在,我们才能对字典、集合这些无序类型做循环取值
2.如何判断迭代器对象
内置有__iter__和__next__的对象都称作迭代器对象
3.可迭代对象与迭代器对象的关系
可迭代对象调用__iter__方法之后就会变成迭代器对象
迭代器对象调用__iter__方法无论多少次还是迭代器对象本身
4.迭代器对象迭代取值
eg:
res = 'xiao'.__iter__()
print(res.__next__()) # x
print(res.__next__()) # i
print(res.__next__()) # a
print(res.__next__()) # o
print(res.__next__()) # 报错
5.迭代器对象无论调用多少次__iter__,都还是自己本身
eg:
l1 = [1,2,3,4,5]
print(l1.__iter__().__next__()) # 1
print(l1.__iter__().__next__()) # 1
print(l1.__iter__().__next__()) # 1
l1 = [1,2,3,4,5]
res = l1.__iter__()
print(res.__iter__().__next__()) # 1
print(res.__iter__().__next__()) # 2
print(res.__iter__().__next__()) # 3
print(res.__iter__().__next__()) # 4
print(res.__iter__().__next__()) # 5
6.针对双下方法 可以简写为: 方法名()
eg:
res = l1.__iter__() # iter(l1)
res.__next__() # next(res)
for循环本质
1.语法结构
for 变量名 in 可迭代对象:
for循环体代码
2.本质
2.1 for会自动将in后面的数据调用__inter__()变成迭代器对象
2.2 之后每次循环调用__next__()取值
2.3 最后没有值__next__()会报错 for 能够自动处理该错误 让循环正常结束