函数2
python函数2
一、生成器
-
python社区,生成器与迭代器看成是一种。生成器的本质就是迭代器。唯一的区别:生成器是我们自己用python代码构建的数据结构。迭代器都是提供的,或者转化得来的。
-
获取生成器的三种方式:
- 生成器函数。(返回的是个生成器)
- 生成器表达式。
- python内部提供的一些。
-
生成器函数
-
yield
-
#只要函数中有yield那么它就是生成器函数而不是函数了。 # 生成器函数中可以存在多个yield,yield不会结束生成器函数,一个yield对应一个next def gen_func(): for i in range(1,5001): yield f'{i}号包子' ret = gen_func() # [3号包子.] for i in range(200): print(next(ret)) for i in range(200): print(next(ret))
-
-
yield from(把作用对象作为迭代器返回)
-
def func(): lst1 = ['卫龙', '老冰棍', '北冰洋', '牛羊配'] lst2 = ['馒头', '花卷', '豆包', '大饼'] yield from lst1 yield from lst2 g = func() for i in range(8): print(next(g))
-
-
-
各种推导式
-
列表推导式
-
循环模式:[变量(加工后的变量) for 变量 in iterable]
# 从python1期到python100期写入列表lst print([f'python{i}期' for i in range(1,101)]) print(['python{t}期'.format(t=i) for i in range(1,101)]) print(['python%s期'%(i) for i in range(1,101)]) -
筛选模式:[变量(加工后的变量) for 变量 in iterable if 条件]
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] print([name.upper() for i in names for name in i if name.count('e') == 2])
-
-
生成器表达式
obj = (i for i in range(1,11)) print(next(obj)) print(next(obj)) -
字典推导式(了解)
lst1 = ['jay', 'jj', 'meet'] lst2 = ['周杰伦','林俊杰','元宝'] dic = { lst2[i]: lst1[i] for i in range(len(lst1))} -
的集合推导式(了解)
print({i for i in range(1,11)})
-
二、内置函数
-
python提供了68个内置函数
-
eval 剥去字符串的外衣运算里面的代码,有返回值。
- 字符串里面一定要是可以执行的代码,不能是一个变量没有赋值,字符串里面可以是字符串
- 网络传输的str input 输入的时候,sql注入等等绝对不能使用eval。
s1='1+3' print(s1) print(eval(s1),type(eval(s1)))#一个读取文件的eval运用(之前用于淘宝抢单的很长的cookie) with open('ww.txt',encoding='utf-8',mode='r') as f: tt=f.read() t=eval(tt)#脱一次,txt默认都是字符串 print(t,type(t)) t1=eval(t)#再脱一次,变成list print(t1, type(t1)) -
exec 与eval几乎一样, 代码流。
-
help(str)帮助文件
-
callable 判断一个对象是否可被调用
s1 = 'fdsklfa' # s1() def func(): pass # func # # callable 判断一个对象是否可被调用 *** # print(callable(s1)) # print(callable(func)) -
复数
print(complex(1,2)) # (1+2j) -
进制转换
bin:将十进制转换成二进制并返回。 ** oct:将十进制转化成八进制字符串并返回。 ** hex:将十进制转化成十六进制字符串并返回。 ** -
divmode/roung/pow
print(divmod(10,3)) print(round(3.141592653, 2)) # 3.14 print(pow(2,3)) ** print(pow(2,3,3)) # 2**3 % 3 -
byte/ord/chr
s1 = '太白' b = s1.encode('utf-8') print(b) b = bytes(s1,encoding='utf-8') print(b)对于使用ord ,ascii里有,找ascii位置,没有,去找 Unicode中的位置 print(ord('a')) # print(ord('中')) # 20013 Unicode # chr:输入位置数字找出其对应的字符 # ** # print(chr(97)) print(chr(20013)) # Unicode -
repr
repr:返回一个对象的string形式(原形毕露) s1 = '存龙' print(repr(s1))#连引号也给你返回的!!!!!!!! -
all/any
all:可迭代对象中,全都是True才是True any:可迭代对象中,有一个True 就是True -
sum
l1 = [i for i in range(10)] s1 = '12345' print(sum(l1,100)) print(sum(s1)) # 错误 -
reverse
# reversed 返回的是一个翻转的迭代器 *** # l1 = [i for i in range(10)] # # l1.reverse() # 列表的方法 -
zip
zip 拉链方法 -
min/max
- min默认会按照字典的键去比较大小。!!!!
dic = {'a': 3, 'b': 2, 'c': 1} print(min(dic)) # min默认会按照字典的键去比较大小。答案a print(min(dic,key=lambda args: dic[args])) #它会自动的将可迭代对象中的每个元素按照顺序传入key对应的函数中,答案c,还是返回键值-
sorted
- sorted也好,min也罢,当有key时,都会把可迭代对象每个值传进,比较好后,再根据比较好的结果把这传进去的值返回,这也是为什么dict返回键,元祖型列表返回是元祖
l2 = [('大壮', 76), ('雪飞', 70), ('纳钦', 94), ('张珵', 98), ('b哥',96)] print(sorted(l2)) l2.sort()#也可以哦 print(sorted(l2,key= lambda x:x[1])) # 返回的是一个列表,默认从低到高 print(sorted(l2,key= lambda x:x[1],reverse=True)) # 返回的是一个列表,默认从高到低
-
filter
- 制造迭代器
- list(迭代器或者迭代对象都可以哦)!!!****************
- 把所有true的都返回
l1 = [2, 3, 4, 1, 6, 7, 8] # print([i for i in l1 if i > 3]) # 返回的是列表 ret = filter(lambda x: x > 3,l1) # 返回的是迭代器,把所有true的都返回 print(ret) print(list(ret)) -
map
- map 列表推导式的循环模式
l1 = [1, 4, 9, 16, 25] print([i**2 for i in range(1,6)]) # 返回的是列表 ret = map(lambda x: x**2,range(1,6)) # 返回的是迭代器 print(ret) print(list(ret)) -
reduce
# reduce from functools import reduce def func(x,y): ''' 第一次:x y : 11 2 x + y = 记录: 13 第二次:x = 13 y = 3 x + y = 记录: 16 第三次 x = 16 y = 4 ....... ''' return x + y l = reduce(func,[11,2,3,4]) print(l) -
关于time/datetime的使用
import time import datetime t1=time.time() t2=time.localtime() t3=time.strftime("%Y:%m:%d:%H:%M:%S:%A",t2) t4=time.strptime(t3,"%Y:%m:%d:%H:%M:%S:%A") t5=datetime.date(year=10,month=2,day=19) t6=datetime.time(second=10) t7=datetime.datetime(year=10,month=2,day=19,second=19) t8=datetime.datetime.now() t9=t8.strftime("%Y:%m:%d:%H:%M:%S.%f:%A") def ff(*args): print(args) ff(t1,t2,t3,t4,t5,t6,t7,t8,t9) -
关于ramdom模块
import random # 获取[0.0,1.0)范围内的浮点数 print(random.random()) # # 获取[a,b)范围内的浮点数 print(random.uniform(3,5)) # # 获取[a,b]范围内的一个整数 # print(random.randint(3,10)) lst = list(range(10)) random.shuffle(lst)#shuffle是洗牌的意思 print(lst) t = (1,2,3) # random.shuffle(t) # 通过sample变相实现打乱 lst = random.sample(t,len(t)) print(lst)
-
三、匿名函数
-
func1 = lambda a,b: a + b print(func1(1,2)) lambda a,b: a if a > b else b
四、闭包
-
闭包1,闭包只能存在嵌套函数中。2, 内层函数对外层函数非全局变量的引用(使用),就会形成闭包。
-
闭包是保障变量安全的。当多次引用函数内部的变量时,没有闭包就要设全局变量,就不安全,不设全局变量,局部变量每次引用又会清空。
- averager这步真的很关键,如果没有这个,averager的地址和内容就会消失,这一步相当于保留了地址,才有了后面内层函数对外函数的非全局变量的引用,才有闭包
def make_averager(): l1 = [] def averager(new_value): l1.append(new_value) print(l1) total = sum(l1) return total/len(l1) return averager avg = make_averager() # averager这步真的很关键,如果没有这个,averager的地址和内容就会消失,这一步相当于保留了地址,才有了后面内层函数对外函数的非全局变量的引用,才有闭包 # print(avg(100000)) # print(avg(110000)) # print(avg(120000)) # print(avg(190000))
五、装饰器
-
装饰器的原则和作用
-
开放封闭原则:1.为其增加新的功能 2.在不改变原函数的代码以及调用方式的前提下
-
下面代码的问题是不满足封闭原则,因为改变了调用方式(为了实现测量时间功能,需要单独调用一遍index,而不是在调用index的同时实现测量时间的功能)
-
import time def index(): '''有很多代码.....''' time.sleep(2) # 模拟的网络延迟或者代码效率 print('欢迎登录博客园首页') def dariy(): '''有很多代码.....''' time.sleep(3) # 模拟的网络延迟或者代码效率 print('欢迎登录日记页面') def timmer(f): # f= index start_time = time.time() f() # index() end_time = time.time() print(f'测试本函数的执行效率{end_time-start_time}') timmer(index)#单独调用了哦 #单独调用了哦
-
-
标准装饰器
index = timmer(index),赋予了等式左边index新的含义,使其指向inner,等式右边的index用到了闭包的概念,再次index()会用到index函数
我们要记住装饰器很简单,只要记住@timmer:index=timmer(index),timmer(index)用到闭包,index移花接木来完成封闭原则
import time # timmer装饰器 def timmer(f): def inner(): start_time = time.time() f() end_time = time.time() print(f'测试本函数的执行效率{end_time-start_time}') return inner @timmer # index = timmer(index),赋予了等式左边index新的含义,使其指向inner,等式右边的index用到了闭包的概念,再次index()会用到index函数 def index(): '''有很多代码.....''' time.sleep(0.6) # 模拟的网络延迟或者代码效率 print('欢迎登录博客园首页') return 666 ret = index() print(ret) -
带参数返回的装饰器。
- 我们知道index()其实就是inner(),原生index函数的完全由inner函数调用执行,所以原生index的返回值必须在inner里面接收,所以有了r=f()
import time # timmer装饰器 def timmer(f): def inner(): start_time = time.time() # print(f'这是个f():{f()}!!!') # index() r = f() end_time = time.time() print(f'测试本函数的执行效率{end_time-start_time}') return r return inner @timmer # index = timmer(index) def index(): '''有很多代码.....''' time.sleep(0.6) # 模拟的网络延迟或者代码效率 print('欢迎登录博客园首页') return 666 # 加上装饰器不应该改变原函数的返回值,所以666 应该返回给我下面的ret, # 但是下面的这个ret实际接收的是inner函数的返回值,而666返回给的是装饰器里面的 # f() 也就是 r,我们现在要解决的问题就是将r给inner的返回值。 ret = index() # inner() print(ret) -
最终版标准的装饰器
标准版的装饰器; def wrapper(f): def inner(*args,**kwargs): '''添加额外的功能:执行被装饰函数之前的操作''' ret = f(*args,**kwargs) ''''添加额外的功能:执行被装饰函数之后的操作''' return ret return inner
浙公网安备 33010602011771号