4.7 推导式
-
列表推导式
-
基本格式
v1 = [i for i in 可迭代对象 ]
v2 = [i for i in 可迭代对象 if 条件 ] # 条件为true才进行append1 # 示例一 2 v1 = [ i for i in 'alex' ] # ['a','l','e','x'] 3 v2 = [i+100 for i in range(10)] # [100,101,102,...,109] 4 v3 = [99 if i>5 else 66 for i in range(10)][66,66,66,66,66,66,99,99,99,99] 5 6 # 示例二 7 def func(): 8 return 100 9 v4 = [func for i in range(10)] # [10个func函数] 10 11 v5 = [lambda : 100 for i in range(10)] 12 result = v5[9]() # 100 13 14 # 示例三 15 def func(): 16 return i 17 v6 = [func for i in range(10)] 18 result = v6[5]() # 9 19 20 v7 = [lambda :i for i in range(10)] 21 result = v7[5]() # 9 22 23 # 示例四 24 v8 = [lambda x:x*i for i in range(10)] # 新浪微博面试题 25 # 1.请问 v8 是什么?# 函数 26 # 2.请问 v8[0](2) 的结果是什么? # 18 27 28 # 面试题 29 def num(): 30 return [lambda x:i*x for i in range(4)] 31 # num() -> [函数,函数,函数,函数] 32 print([ m(2) for m in num() ]) # [6,6,6,6] 33 34 # ##################### 筛选 ######################### 35 v9 = [i for i in range(10) if i > 5]
-
-
集合推导式
v1 = { i for i in 'alex' }
-
字典推导式
v1 = { 'k'+str(i):i for i in range(10) }
4.8 装饰器
-
导入
# 典例一 v = 1 v = 2 print(v) # 2 # 典例二 def func(): pass v = 10 v = func print(v) # v 为函数地址 # 典例三 def base(): print(1) def bar(): print(2) bar = base bar() # 1 # 典例一 def func(): def inner(): pass return inner v = func() # inner函数地址 # 典例二 def func(arg): def inner(): print(arg) return inner v1 = func(1) v1() # 1 v2 = func(2) v2() # 2 # 典例三 def func(arg): def inner(): arg() return inner def f1(): print(123) v1 = func(f1) v1() # 123 # 典例四 def func(arg): def inner(): arg() return inner def f1(): print(123) return 666 v1 = func(f1) #inner函数 result = v1() #执行f1函数 123 print(result) #返回值为None # 典例五 def func(arg): def inner(): return arg() return inner def f1(): print(123) return 666 v1 = func(f1) # inner函数 result = v1() # 执行inner函数 123 返回值为f1 print(result) #打印f1返回值
-
装饰器基本格式
def func(age):
def inner():
v = arg()
return v
return inner
# 第一步:执行func函数并将下面函数参数传递,相当于:fun(index)
# 第二步:将func的返回值重新赋值给下面的函数名,index = func(index) -
含义
-
在不改变原函数内部代码的 基础上,在函数执行之前和之后自动执行某个功能
-
-
格式
-
装饰器编写格式
def 外层函数(参数):
def 内层函数(*args,**kwargs)
return 参数(*args,**kwargs)
return 内层函数 -
装饰器应用格式
-
问题:为什么要加 *args, **kwargs
-
可以接收参数函数里面任意值
-
-
如果给好几个函数写一个统一的装饰器,怎么办?
def a1(func):
def inner(*args,**kwargs)
return func(*args,**kwargs)
return inner
-
-
关于执行函数的前后
def a1(func):
def inner(*args,**kwargs)
print("调用函数之前")
data = func(*args,**kwargs)# 执行函数并获取返回值
print("调用函数之后")
return data
return inner
-
带参数的装饰器
# 第一步:执行 ret = xxx(index)
# 第二步:将返回值赋值给 index = ret# 格式
def x(counter):
def wrapper(fnc):
def inner(*args,**kwargs)
data = func(*args,**kwargs)
return data
return inner
def wrapper
-
查看带参数装饰器执行顺序
def x(counter):
print('x函数')
def wrapper(func):
print('wrapper函数')
def inner(*args,**kwargs):
print('inner函数')
if counter:
return 123
return func(*args,**kwargs)
return inner
return wrapper
4.9 迭代器
-
类和对象
-
任务展示列表中所有数据
-
while + 索引 + 计数器
-
迭代器
-
-
迭代器含义
对某种对象(str/list/tuple/dict/set类创建的对象),可迭代对象中元素逐一获取。
什么是迭代器:具有' __ next __ ' 的方法且每次调用都能获取可迭代对象中的每个元素(从前到后一一获取)
-
迭代器使用
# 列表转换成迭代器:
v1 = [1,2,3,4]
v2 = iter(v1) #v2就是迭代器
v2 = v1.__iter__()
# 迭代器想要获取每个值:
result1 = v2.__next__()
print(result1)
result2 = v2.__next__()
print(result2)
result3 = v2.__next__()
print(result3)
result4 = v2.__next__()
print(result4)
result5 = v2.__next__()
print(result5)
# 直到报错:StopIteration错误,表示已经迭代完毕。
# 或者循环获取迭代器中的内容
while True:
try:
val = v2.__next__()
print(val)
except Exception as e:
break-
如何判别一个对象是否是迭代器:内部是否有
__next__方法
。 -
for循环实质
v1 = [11,22,33,44]
# 1.内部会将v1转换成迭代器
# 2.内部反复执行 迭代器.__next__()
# 3.取完不报错
for item in v1:
print(item)
-
-
可迭代对象
-
表象:可以被循环对象就可以称为是可迭代对象:"x" [1,2] {}
class Foo:
pass
obj = Foo() -
内部具有
__iter__()
方法且返回一个迭代器。v1 = [11,22,33,44]
result = v1.__iter__() #result 就是迭代器 -
可以被for循环
-
如何让一个对象变成可迭代对象?
在类中实现
__iter__
方法且返回一个迭代器(生成器)class Foo:
def __iter__(self):
return iter([1,2,3,4])
obj = Foo()
class Foo:
def __iter__(self):
yield 1
yield 2
yield 3
obj = Foo记住:只有能被for循环就是去看内部的iter方法。
-
-
迭代器口诀
-
取一次就没有了
-
不取就不执行
-
-
取迭代器的值得方法
-
list
-
for循环
-
next
-
4.10 生成器
-
实质:就是函数的变异
-
格式
# 生成器函数(内部是否包含yield)
def func():
print("f1")
yield 1
print("f2")
yield 2
print("f3")
# 函数内部不会被执行,返回一个生成对象
v1 = func()
# 生成器可以被for循环,一旦开始循环那么函数内部代码就会开始执行
for item in v1:
print(item)# 无限循环打印1,2,3.....
def func():
count = 1
while True:
yield count
count += 1
val = func()
for item in val:
print(item) -
总结:函数中如果存在yield,那么该函数就是一个生成器函数,调用生成器函数会返回一个生成器,生成器只有被for循环时,生成器函数内部的代码才会被执行,每次执行都会获取yield返回的值
-
练习
# 读取大文件
def func():
"""
分批去读取文件中的内容,将文件的内容返回给调用者。
:return:
"""
cursor = 0
while True:
f = open('db', 'r', encoding='utf-8')# 通过网络连接上redis
# 代指 redis[0:10]
f.seek(cursor)
data_list =[]
for i in range(10):
line = f.readline()
if not line:
return
data_list.append(line)
cursor = f.tell()
f.close() # 关闭与redis的连接
for row in data_list:
yield row
for item in func():
print(item)redis 源码示例
个人站点 www.danpinsuiyue.com ,欢迎给各位大神莅临本博客空间。