首页 > 其他 > 详细

4)装饰器、迭代器、生成器以及内置函数

时间:2018-04-25 10:51:38      阅读:239      评论:0      收藏:0      [点我收藏+]
                装饰器、迭代器、生成器以及内置函数

 

 

装饰器:

原函数前后增加功能,切不改变函数的原本使用方式

 

import time
def wrapper(f):
    def inner():
        start = time.time()
        f()
        end = time.time()
        print('执行效率为%s'%(end-start))
    return inner

@wrapper
def func():
    print('this is func')
    time.sleep(0.3)
func()

 

import time
def wrapper(f):
    def inner(*args,**kwargs):#带参数的装饰器
        start = time.time()
        f(*args,**kwargs)
        end = time.time()
        print('执行效率为%s'%(end-start))
    return inner

@wrapper
def func(a,b):
    print(a,b)
    print('this is func')
    time.sleep(0.3)
func(111,222)

 

 

再加一个666

import time
def wrapper(f):
    def inner(*args,**kwargs):#带参数的装饰器
        start = time.time()
        set = f(*args,**kwargs)
        end = time.time()
        print('执行效率为%s'%(end-start))
        return set
    return inner

@wrapper
def func(a,b):
    print(a,b)
    print('this is func')
    time.sleep(0.3)
    return 666
print(func(111,222))

 

 

进阶需求:

情况一:

500个函数

   设计装饰器,确认是否生效

import time
FLAG = True
def outer(flag):
    def wrapper(f):
        def inner(*args,**kwargs):#带参数的装饰器
            if flag == True:

                start = time.time()
                set = f(*args,**kwargs)
                end = time.time()
                print('执行效率为%s'%(end-start))
            else:
                set = f(*args,**kwargs)
            return set
        return inner
    return wrapper

@outer(FLAG)
def func(a,b):
    print(a,b)
    print('this is func')
    time.sleep(0.3)
    return 666
print(func(111,222))

 

 

情况二:

登陆,纪录日志

 

 

 

login_info = {'alex':False}

def login(func):
    def inner(name):
        if login_info[name] !=True:
            user = input('>>>user')
            pwd = input('>>pwd')
            if user =='alex' and pwd =='alex3714':
                login_info[name] = True
        if login_info[name]  == True:
             ret = func(name)
             return ret
    return inner


def wrapper1(func):   #f
    def inner1():
        print('wrapper1 ,before func')
        func()   # f
        print('wrapper1 ,after func')
    return inner1

def wrapper2(func):  # inner1
    def inner2():
        print('wrapper2 ,before func')
        func()   # inner1
        print('wrapper2 ,after func')
    return inner2

@wrapper2
@wrapper1
def f():
    print('in f')

f()

 

 技术分享图片

 

import time
login_info = {'alex':False}
def login(func):
    def inner(name):
        if login_info[name] !=True:
            user = input('>>>user')
            pwd = input('>>pwd')
            if user =='alex' and pwd =='alex3714':
                login_info[name] = True
        if login_info[name]  == True:
             ret = func(name)
             return ret
    return inner

def timmer(f):
    def inner(*args,**kwargs):
        start = time.time()
        ret = f(*args,**kwargs)
        end = time.time()
        print('执行效率%s'%(end-start))
        return ret
    return inner
@login
@timmer
def index(name):
    print('欢迎%s考到博客园'%name)
    time.sleep(0.3)
@login
@timmer
def manager(name):
    print('欢迎%s考到博客园管理页面'%name)
    time.sleep(0.3)
index('alex')
manager('alex')

 

迭代器和生成器

 

迭代器:

凡是可以使用for循环取值的都是可迭代的

#从列表、字典中取值
# index索引
#for 凡是通过for循环取值的都是可迭代的

 

 

可迭代协议:

内部有__iter__方法的都是可迭代的

 

迭代器协议:

内部有__iter____next__方法的都是迭代器

创建迭代器使用__iter__() 或者 iter()

dir()可以查看使用的内置方法

l = [1,2,3]
ll = iter(l)
print(ll.__next__())
print(ll.__next__())

 

 

l = [1,2,3]
lst_iter = iter(l)  #lst_iter = iter(l) == lst_iter = [1,2,3].__iter__()

while True:
    print(next(lst_iter))   #lst_iter.__next__()

 

 

 

l = [1,2,3]
ll = iter(l)
while True:

    print(next(ll))   #报错了

 

 

没有就会出错

l = [1,2,3]
lst_iter = iter(l)  #lst_iter = iter(l) == lst_iter = [1,2,3].__iter__()

while True:
    try:
        print(next(lst_iter))   #lst_iter.__next__()
    except StopIteration:
        break

 

 

 

 

总结:

什么是可迭代:内部有__iter__

 

什么是迭代器:迭代器=iter(可迭代的) 自带__next__方法

节省内存

 

Range()

 

from collections import  Iterable,Iterator
print(range(10000))
print(isinstance(range(10000),Iterable))  #True
print(isinstance(repr(10000),Iterator))   #False


 

 

Python2range会生成一个列表,将用来存储生成所有的值

 技术分享图片

Python3range不管要多少,都不会生成实际的值

在使用的时候在生成

for i in range(1000):

 

节省内存,速度快

特性:惰性运算

 

 

生成器:

自己写的迭代器就是生成器

两种自己写生成器的机制:

生成器函数:

凡是带有yield的函数是个生成器

 

def func():
    print('****')
    yield 1
g = func()
next(g)

 

 

 

def func():
    print('****')
    yield 1
    print('^^^^')
    yield 2
g = func()
print('___',next(g))
print('===',next(g))

 

 

 

Yield 记录当前所在位置,等待下一次next来触发函数的状态

想要执行要next

def cloth_g(name):
    for i in range(name):
        yield 'choth_g%s'%i
g = cloth_g(10)
next(g)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))

 

 

 

 

使用生成器监听文件输入:

import time
def lister_file():
    with open('userinfo') as f1:
        while True:
            line = f1.readline()
            if line.strip():
                yield line.strip()
            time.sleep(0.3)

g = lister_file()
for i in g:
    print(i)
    if i =='error':
        break

 

 

 

 

 技术分享图片

 

Send 关键字

在执行next的时候,传递一个参数给生成器函数的内部

1)

def func():
    print(1111)
    yield 1
    print(2222)
    yield 2
    print(3333)
    yield 3

func()
next(func())
next(func())

 

 

 

 

2) :

def func():
    print(1111)
    yield 1
    print(2222)
    yield 2
    print(3333)
    yield 3

g = func()
ret = next(g)
print(ret)

 

 技术分享图片

3) :

 

def func():
    print(1111)
    ret1 = yield 1
    print(2222,'ret1:',ret1)
    ret2 = yield 2
    print(3333,'ret2:',ret2)
    yield 3

g = func()
ret = next(g)
print(g.send('alex'))
print(g.send('lxf'))

 

 

 

向生成器中传递值,有个激活过程,第一次必须用next触发这个生成器

def average():
    sum_money = 0  #总钱数
    day = 0   #天数
    avg = 0   #平均的钱
    while True:
        money = yield avg
        sum_money += money
        day +=1
        avg =  sum_money/day
g = average()
next(g)
print(g.send(200))
print(g.send(300))

 技术分享图片

 

 

例子:

 

 

 

预激生成器:

就是吧要激活的next放到一个装饰器当中,比如说有多个程序需要激活的话,可以这样做,为了简便,如果要是就一个程序的话就没有必要了

 

yield from

 

 

 

def generator_func():
    for i in range(5):
        yield i
    for j in 'hello':
        yield j
g = generator_func()

#如何取值

#1,next、随时可以停止,最后会报错
print(next(g))
print(next(g))

#2,for循环、从头到尾遍历一次,不遇到break、return不停止
for i in g:
    print(i)


#3,list、tuple
print(list(g))#一次性所有的都转换了,如果多太占内存
print(g)

 

上面的内容可以进行替换成如下:

def generator_func():
    yield from range(5)
    yield from 'hello'
    # for i in range(5):
    #     yield i
    # for j in 'hello':
    #     yield j
g = generator_func()
for i in g:
    print(i)

 

总结:

 

1)生辰器函数,是我们python程序员实现迭代器的一种手段

2)主要特征是在函数中含有yield

3)调用一个生成器函数,不会执行这个函数中的代码,只是会获得一个生成器代码

4)只有从生辰器中取值的时候,才会执行函数内部的代码,且每获取一个数据才执行的到这个数据的代码

5)获取数据方式,nextsend 循环 数据类型的强制转化

6)Yield 返回值的简便方法,如果本身就是循环一个可迭代,且要把可迭代数据中的每一个元素都返回,可以用yield from

7)使用send的时候,在生成器创造出来之后需要进行预激活,这一步可以使用装饰器完成

8)生成器特点:节省内存、惰性运算

9)生成器用来解决内存和程序功能之间的解耦

 

 


 

 

 

 

列表推到试:表现为   []

new = []
for i in range(10):
    new.append(i**2)
print(new)

 


#上面的复杂不好
print([i **2 for i in range(10)])#列表推到式

 

 

ll = [1,2,3,-5,6,20,-7]#求每个数的余数
print([ i%2 for i in ll])

 

 

ll = [1,2,3,-5,6,20,-7]
print([i for i in ll if i %2 ==0])

 

#30以内搜友能被3整除的数
print([i for i in range(30) if i % 3 ==0])
#30以内搜友能被3整除的数的平方
print([i**2 for i in range(30) if i % 3 ==0])

#:找到嵌套列表中名字含有两个‘e’的所有名字
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
         ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
# for i in names:
#     for j in i:     #复杂不好
#         if j.count('e') ==2:
#             print(j)

print( [j for i in names for j in i if j.count('e') ==2])

 

 

生成器表达式:表现为 ()

 

 技术分享图片

 

 

练习题:

 

 技术分享图片

 

自定义函数:

自己定义的【name = uuu’】

 

 

内置函数:

拿过来直接用的,python直接封装好的

Printlenmaxmindir

 

迭代器/生成器相关的:

Rangenext iter

 

作用域相关的:

Globals

Locals

 

其他:

Input

Print:九九乘法表
for i in range(1,10):
    for j in range(1,i+1):
        print('%s*%s=%2s'%(i,j,i*j),end=' ')
    print()

 

print(1,2,3,4,5,sep=';',end=' ')#1;2;3;4;5
print(1,2,3,4,5,sep=';',end='')#1;2;3;4;5

 

 

进度条

import time
for i in range(0,101,2):
    time.sleep(0.1)
    char_num = i//2
    per_str = '\r%s%% : %s\n' % (i, '*' * char_num) if i ==100 else'\r%s%% : %s'%(i,'*'*char_num)
    print(per_str,end='')

 

 

import time
for i in range(0,101,2):
    time.sleep(0.1)
    char_num = i//2
    if i ==100:
        per_str = '\r%s%% : %s\n' %(i,'*'* char_num)
    else:
        per_str='\r%s%%: %s'%(i,'*' *char_num)
    print(per_str,end='')

 

 

 

Hash

对可hash的数据类型进行hash之后会的到一个数字
在一次程序的执行过程中,对相同的可哈希变量,哈希之后的结果永远相同
在一次程序的执行过程中,对不相同的可哈希变量,哈希之后的结果几乎是不相同的
hash字典底层的存储和set 集合的去重机制都有关

 

Id():

Open

Import

Help

Callable:可调用

def func():
    pass
a = 1
print(callable(func))#True
print(callable(a))#False

 

 

Dir: 查看这一个变量的所有方法、属性

Bin:进制


print(bin(10))#二进制
print(oct(10))#十进制
print(hex(10))#十六进制


abs计算数字绝对值

print(abs(4))
print(abs(-4))

 

 

divmod:商余函数

print(divmod(10,2))#(5, 0)
print(divmod(7,3))#(2, 1)
print(divmod(9,7))#(1, 2)

 

 

Round:小数精确

print(round(3.1415926,4))#3.1416  小数精确四舍五入

 

 

Pow:平方

print(pow(2,3))#8
print(pow(3,2))#9

 

 

Sum:求和

print(sum([1,2,3,4,5]))

 

 

Min:计算最小值

print(min([1,2,3,4,5]))#1
print(min([1,2,3,4,5]))#1
print(min(1,-2,3,-4,key=abs))#1

 

 


def func(num):
    return num%2
print(min(-2,3,-4,key=func))

 

Max:和min一样

 

List

Tuper

Reverse:反转

Reversed()
ret = [1,2,3,4,5]
ret1 = reversed(ret)
ret2 = reversed((1,2,3,4,5))
print(ret)#[1, 2, 3, 4, 5]
print(list(ret1))#[5, 4, 3, 2, 1]
print(list(ret2))#[5, 4, 3, 2, 1]

 

 

Str

Format

Bytes

Ord

 

 

print(ord('a'))#小写的a-z   97+26   大写的A-Z 65+26

 

Chr

print(chr(97))#a


Repr:
print(repr(1))#1
print(repr('1'))#'1'

 

 

 

Enumerate:枚举函数

 

l = ['苹果','香蕉','橘子']
for index,i in enumerate(l,1):
    print(index,i)

 

l = ['苹果','香蕉','橘子']
ret = enumerate(l,1)
for i in ret:
    print(i[0],i[1])

 

 

 

 

没啥用:

 技术分享图片

 

Zip:拉链方法:

ss =zip([1,2,3,4],('a','b','c','d'))
for i in ss:
    print(i)

 

 

 

 

Filter用于过滤不需要的元素


ll = [1,4,6,7,12,17]
def func(num):
    if num %2 ==0:return True
for i in filter(func,ll):
    print(i)

g=(i for i in ll if i%2 ==0)

 

 


l = ['test',None,'','str', ' ','END']
def func(item):
    if item and item.strip():return True
for i in filter(func,l):
    print(i)

 

 

 

Map

def func(num):
    return num**2
for i in map(func,range(10)):print(i)

 

 

Sorted:排序功能

 


l = [1,-4,-2,3,-5,6,5]
l.sort(key=abs)
print(l)

 

 


l = [1,-4,-2,3,-5,6,5]
new = sorted(l,reverse=True)
print(new)


 

 

 

l = [[1,2,],[3,4,5,6],(7,),'123']
print(sorted(l,key=len))

 

 

eval

eval('print(123)')

 

 

exec

exec ('print(123)')#123
eval('print(123)')#123

print(eval('1+2-3*20/(2+3)')) -9.0
print(exec('1+2-3*20/(2+3)'))# none

 

 

 

匿名函数:

Lambda表达式:

逻辑比较简单
1):

add = lambda a,b: a+b
print(add(1,2))



2):

def func(num):
    return num**2
for i in map(func,range(10)):print(i)



for i in map(lambda num : num**2,range(10)):print(i)

 

 

 

 

3):
def func(num):
    return num%2
print(max(-2,3,-4,key=func))


print(max(-2,3,-4,key=lambda num:num%2))

 

 

 

 

 

递归:

 

 技术分享图片

 

 

 技术分享图片

 

  技术分享图片

 

递归自己调用自己

需要有一个停止的条件

技术分享图片 


4)装饰器、迭代器、生成器以及内置函数

原文:http://blog.51cto.com/xiaorenwutest/2107559

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!