day-5 装饰器 迭代器 生成器
1.装饰器
1.1 带参数的装饰器
参数可以用来决定是否执行某个装饰器的某一部分
def outer(flag):
def timer(func):
def inner(*args,**kwargs):
if flag:
print('''执行函数之前要做的''')
re = func(*args,**kwargs)
if flag:
print('''执行函数之后要做的''')
return re
return inner
return timer
@outer(False)
def func():
print(111)
执行结果为111
@outer(True)
def func():
print(111)
执行结果为
执行函数之前要做的
111
执行函数之后要做的
1.2多个装饰器装饰一个函数
注意执行顺序
def wrapper1(func):
def inner():
print('wrapper1 ,before func')
func()
print('wrapper1 ,after func')
return inner
def wrapper2(func):
def inner():
print('wrapper2 ,before func')
func()
print('wrapper2 ,after func')
return inner
@wrapper2
@wrapper1
def f():
print('in f')
f()
执行结果为:
wrapper2 ,before func
wrapper1 ,before func
in f
wrapper1 ,after func
wrapper2 ,after func
2.迭代器、生成器
2.1可迭代对象
字符串、列表、元组、字典、集合都可以被for循环,说明他们都是可迭代的。
from collections import Iterable
l = [1, 2, 3, 4]
t = (1, 2, 3, 4)
d = {1: 2, 3: 4}
s = {1, 2, 3, 4}
str = '1234'
print (isinstance (l, Iterable))#True
print (isinstance (t, Iterable))#True
print (isinstance (d, Iterable))#True
print (isinstance (s, Iterable))#True
print (isinstance (str, Iterable))#True
用dir查看具有的方法,如果有__iter__则表示可迭代的。
str = '1234'
print('__iter__' in dir(str))#True
2.2迭代器
英文为iterator;将可迭代的转化为迭代器。
l = [1,2,3,4]
l_iter = l.__iter__() # 将可迭代的转化成迭代器
print(l_iter)# <list_iterator object at 0x000001C691D284E0>
item = l_iter.__next__()
print(item)#1
item = l_iter.__next__()
print(item)#2
__next__()一直向前取值,不回头。
迭代器遵循迭代器协议:必须拥有__iter__方法和__next__方法。
for循环,能遍历一个可迭代对象, 将可迭代对象转化成迭代器。(可迭代对象.__iter__());内部使用__next__方法,一个一个取值;加了异常处理功能,取值到底后自动停止。
迭代器的好处:
迭代器,在for循环时,同一时刻在内存中只出现一条数据,极大限度的节省了内存~
2.3初始生成器
1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行
2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表
生成器Generator:
本质:迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现)
特点:惰性运算,开发者自定义
2.4 生成器函数
例子1
import time
def genrator_fun1():
a = 1
print('现在定义了a变量')
yield a
b = 2
print('现在又定义了b变量')
yield b
g1 = genrator_fun1()
print('g1: ',g1) #g1: <generator object genrator_fun1 at 0x0000023859EE03B8>
print(next(g1))#1
time.sleep(1) #sleep一秒看清执行过程
print(next(g1))#2
例子2
def generator():
print(123)
content = yield 1
print('=======',content)
print(456)
yield 2
print('=======',content)
g = generator()
ret = g.__next__()
print('***',ret)
ret = g.send('hello') #send的效果和next一样
print('***',ret)
运行结果:
123
*** 1
======= hello
456
*** 2
3.列表推导式
l = [i for i in range(10)]
print(l)
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
l1 = ['选项%s'%i for i in range(10)]
print(l1)
#['选项0', '选项1', '选项2', '选项3', '选项4', '选项5', '选项6', '选项7', '选项8', '选项9']
4.内置函数,匿名函数
4.1内置函数
什么是内置函数?就是Python给你提供的,拿来直接用的函数,比如print,input等等。截止到python版本3.6.2,现在python一共为我们提供了68个内置函数。
|
内置函数 |
|
|
|
abs() |
dict() |
help() |
min() |
setattr() |
all() |
dir() |
hex() |
next() |
slice() |
any() |
divmod() |
id() |
object() |
sorted() |
ascii() |
enumerate() |
input() |
oct() |
staticmethod() |
bin() |
eval() |
int() |
open() |
str() |
bool() |
exec() |
isinstance() |
ord() |
sum() |
bytearray() |
filter() |
issubclass() |
pow() |
super() |
bytes() |
float() |
iter() |
print() |
tuple() |
callable() |
format() |
len() |
property() |
type() |
chr() |
frozenset() |
list() |
range() |
vars() |
classmethod() |
getattr() |
locals() |
repr() |
zip() |
compile() |
globals() |
map() |
reversed() |
__import__() |
complex() |
hasattr() |
max() |
round() |
|
delattr() |
hash() |
memoryview() |
set() |
|
常用的内置函数:
- eval: 执行字符串类型的代码,并返回最终结果。
eval('2 + 2') # 4
n=81
eval("n + 4") # 85
eval('print(666)') # 666
- exec:执行字符串类型的代码。
s = '''
for i in [1,2,3]:
print(i)
'''
exec(s)
#输出结果:
1
2
3
- 基础数据类型
float:函数用于将整数和字符串转换成浮点数。
进制转换(3):
bin:将十进制转换成二进制并返回。
oct:将十进制转化成八进制字符串并返回。
hex:将十进制转化成十六进制字符串并返回。
print(bin(10),type(bin(10))) # 0b1010 <class 'str'>
print(oct(10),type(oct(10))) # 0o12 <class 'str'>
print(hex(10),type(hex(10))) # 0xa <class 'str'>
- 数学运算
divmod:计算除数与被除数的结果,返回一个包含商和余数的元组(a // b, a % b)。常用于网页页数显示。
sum:对可迭代对象进行求和计算(可设置初始值)。
min:返回可迭代对象的最小值(可加key,key为函数名,通过函数的规则,返回最小值)。
max:返回可迭代对象的最大值(可加key,key为函数名,通过函数的规则,返回最大值)。
# all 可迭代对象中,全都是True才是True
# any 可迭代对象中,有一个True 就是True
# print(all([1,2,True,0]))
# print(any([1,'',0]))
map:会根据提供的函数对指定序列做映射。
def square(x) : # 计算平方数
return x ** 2
map(square, [1,2,3,4,5]) # 计算列表各个元素的平方
[1, 4, 9, 16, 25]
map(lambda x: x ** 2, [1, 2, 3, 4, 5]) # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
4.2 匿名函数
为了解决那些功能很简单的需求而设计的一句话函数。
#这段代码
def calc(n):
return n**n
print(calc(10))
#换成匿名函数
calc = lambda n:n**n
print(calc(10))