1. 装饰器升级
1.1如何让装饰器返回被装饰的函数名称
from functools import wraps
def logger(f):
@wraps(f)
def inner(*args, **kwargs):
"""
:param args: 函数名,密码
:param kwargs: 备用
:return: True
"""
ret = f(*args, **kwargs)
return ret
return inner
@logger
def login(username,password):
print(666)
return True
print(login.__doc__) #打印提示信息
print(login.__name__) #打印被装饰函数名
1.2带参装饰器
1.2.1带一个参数装饰器
def timmerout(flag1): # flag1 =flag
def timmer(f):
def inner(*args,**kwargs):
if flag1:
start_time = time.time()
ret = f(*args,**kwargs)
end_time = time.time()
print('此函数的执行效率%s' % (end_time - start_time))
return ret
else:
ret = f(*args, **kwargs)
return ret
return inner
return timmer
@timmerout(True)
def func2():
time.sleep(0.3)
print('非常复杂......')
return 666
func2()
1.2.2带多个参数装饰器
def timmer(f):
def inner(*args,**kwargs):
if age.isdigit() and name.isalpha():
start_time = time.time()
ret = f(*args,**kwargs)
end_time = time.time()
print('此函数的执行效率%s' % (end_time - start_time))
return ret
else:
ret = f(*args, **kwargs)
return ret
return inner
return timmer
@timmerout(name= 'morgan',age='10') # 1,将@ 与函数分开@ timmerout(flag) 返回了timmer 2,将@timmer结合。
def func1():
time.sleep(0.3)
print('非常复杂......')
return 666
func1()
1.3多个装饰器装饰一个函数
def wrapper1(func): # func = f函数名
def inner1():
print('wrapper1 ,before func') # 2
func() # f函数名()
print('wrapper1 ,after func') # 4
return inner1
def wrapper2(func): # func = inner1
def inner2():
print('wrapper2 ,before func') # 1
func() # inner1()
print('wrapper2 ,after func') # 5
return inner2
def wrapper3(func):
def inner3():
print('wrapper3 ,before func')
func()
print('wrapper3 ,after func')
return inner3
@wrapper3
@wrapper2 # f = warpper2(f) 里面的f是inner1 外面的f是inner2
@wrapper1 # f = warpper1(f) 里面的f函数名 外面的f 是inner1
def f():
print('in f') # 3
f() # inner2()
2.迭代器
- 不可迭代 ‘int’ object is not iterable
- str, list, tuple, dict, set, range, 文件句柄,都是可迭代
- 该对象中,含有iter方法的就是可迭代对象,遵循可迭代协议。
Tips:
dir(str) #查看类中所有方法
2.1判断对象是否为可迭代对象的两种方法
#第一种方法:
print('__iter__' in dir(str))
print('__iter__' in dir(list))
#第二种方法:
from collections import iterable
print(isinstance('abc',Iterable))
print(isinstance('abc',str))
2.2迭代器定义
- 内部含有iter且含有next方法的对象就是迭代器,遵循迭代器协议。
s1 = 'abc'
obj_s = s1.__iter__() #obj_s = iter(s1)将可迭代对象转化为迭代器
print(obj_s.__next__()) #打印迭代器中内容
2.3判断是不是迭代器
#第一种方法:
s1 = 'abc'(可迭代对象)
print('__next__' in dir(s1))
#第二种方法:
from collections import Iterator
print(isinstance('abc', Iterator)) #不是迭代器
l1 = [2,3,4]
l1_obj = l1.__iter__()
print(isinstance(l1_obj, Iterator)) #是迭代器
2.4迭代器重要的3点好处:
- 节省内存
- 惰性机制
- 单向执行,不可逆
#当迭代元素超过实际存在的数量时候,抓取停止错误信息。
s1 = 'morgan'
s1_obj = s1.__iter__()
whileTrue:
try:
print(s1_obj.__next__())
except StopIteration:
break
Tips
for循环内部就是将可迭代对象转化为迭代器。
3.生成器
本质:就是迭代器,他是自定义的迭代器(自己用python代码写得迭代器)“`
def func1():
print(111)
yield 666
print(333)
yield 'morgan'
yield 'abc'
g_obj = func1()
print(g_obj.__next__()) #__next__()和yield必须一一对应
print(g_obj.__next__())
print(g_obj.send(None))
print(g_obj.__next__())
=======================
def func1():
count = yield 666
print(count)
yield 'alex'
yield 'abc'
g_obj = func1() # 生成器对象
print(g_obj.__next__())
print(g_obj.send('morgan'))
print(g_obj.__next__())
'''
send和next都是对生成器取值,
但是send会给上一个yield发送一个值。
send不能用在第一次取值。
最后一个yield不能得到值。
'''
3.1列表推导式
3.1.1遍历模式
l = [i for i in range(1,11)]
【变量(加工后的变量)for 变量 in iterable】
print(l)
3.1.2筛选模式
【变量(加工后的变量)for 变量 in iterable if 条件】筛选模式
l2 = [i for i in range(1,31) if i % 3 == 0]
print(l2)
3.1.3列表推导式好处
- 简单一行搞定
- 特别复杂的数据列表推导式无法实现,只能用其他方式实现。
- 列表推导式不能排错,没法debug
3.2生成器表达式
l2_obj = (i for i in range(1,31) if i % 3 == 0)
print(l2_obj)
3.3生成器表达式与列表推导式区别
1.列表推导式直观能看出,但是占内存
2.生成器表达式不易看出,但是节省内存
3.4字典和集合推导式
字典推导式
mca={"a":1, "b":2, "c":3, "d":4}
dicts={v:k for k,v in mca.items()}
print dicts
结果:
{1: 'a', 2: 'b', 3: 'c', 4: 'd'}
集合推导式
squared={i*2 for i in [1,1,2]}
print(squared)
结果:
{2, 4}
4.内置函数
一共68个
4.1.作用域相关
locals,globals
4.2其他相关
eval
print(eval('1 + 2 +3')) #6
print(eval("{'name':'alex'}"),type(eval("{'name':'alex'}"))) #{'name': 'alex'} <class 'dict'>
exec
(文件读取后都是字符串,可以用其转化为原来的语句)
for i in range(5):
print(i)
'''
exec(s1)
print(1,2,3,sep="*") #分割符,结果:1****2****3
print(111,end='*') #换行,结果:111*
with open('log',encoding='utf-8', mode='w') as f1:
print('good',file=f1) #写文件
- ** id:用于获取对象的内存地址
- 帮助help:函数用于查看函数或模块用途的详细说明
- *hash:获取一个对象(可哈希对象:int,str,Bool,tuple)的哈希值
- compile:将字符串类型的代码编译。代码对象能够通过exec语句来执行或者eval()进行求值
- ** callable:函数用于检查一个对象是否是可调用的。如果返回True,object仍然可能调用失败,但如果返回False,调用对象ojbect绝对不会成功。
- *float:函数用于将整数和字符串转换成浮点数。
- bin:将十进制转换成二进制并返回。
- oct:将十进制转化成八进制字符串并返回。
- hex:将十进制转化成十六进制字符串并返回。
- ***divmod:计算除数与被除数的结果,返回一个包含商和余数的元组(a // b, a % b)。
- *round:保留浮点数的小数位数,默认保留整数。
- *pow:求x**y次幂。(三个参数为x**y的结果对z取余)
- ***sum:对可迭代对象进行求和计算(可设置初始值)
- ***min:返回可迭代对象的最小值(可加key,key为函数名,通过函数的规则,返回最小值)。
- ***max:返回可迭代对象的最大值(可加key,key为函数名,通过函数的规则,返回最大值)。
- reversed:将一个序列翻转,并返回此翻转序列的迭代器。
- *slice:构造一个切片对象,用于列表的切片。
- *format 科学计算
- bytes 将unicode 转化成bytes
- chr 输入位置数字找出其对应的字符
- 是ascii码中的返回该值,不是就返回/u…
- **repr:返回一个对象的string形式(原形毕露)。
- ***sorted:对所有可迭代的对象进行排序操作。
sorted
key就是指可迭代元素
students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
sorted(students, key=lambda s: s[2], reverse=True) # 按降序
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
===========================================================
L=[('b',2),('a',1),('c',3),('d',4)]
sorted(L, key=lambda x:x[1]) # 利用key
[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
***enumerate:枚举,返回一个枚举对象。
enumerate
l1 = ['alex', 'laonanhai', 'taibai']
for index,content in enumerate(l1):
print(index,content)
- **all:可迭代对象中,全都是True才是True
- **any:可迭代对象中,有一个True 就是True
- ***zip 拉链方法
zip
l1 = [1,2,3,]
l2 = ['a','b','c',5]
l3 = ('*','**',(1,2,3),666,777)
for i in zip(l1, l2, l3):
print(i)
结果:
(1, 'a', '*')
(2, 'b', '**')
(3, 'c', (1, 2, 3))
- ***map:会根据提供的函数对指定序列做映射。返回的是迭代器
map
def square(x):
return x ** 2
for i in map(square, [1,2,3,4,5]):
print(i)
结果:
1
4
9
16
25
filter
filter相当于过滤模式推导式
def func(x):return x%2 == 0
ret = filter(func,[1,2,3,4,5,6,7])
for i in ret:
print(i)
匿名函数lamba
func = lambda x,y:x+y
func(3,4)