• 函数进阶篇


    1.1 装饰器

    1.1.1 开放封闭原则:

    对扩展开放,对修改是封闭

    1.1.2 装饰器:

    装饰它人的,器指的是任意可调用对象,现在的场景装饰器-》函数,被装饰的对象也是-》函数

    1.1.3 原则:

    1、不修改被装饰对象的源代码

    2、不修改被装饰对象的调用方式

    1.1.4 装饰器的目的:

    在遵循1,2的前提下为被装饰对象添加上新功能

    错误的示范

    import time
    
    def index():
        time.sleep(3)
        print('welecome to index')
    
    def timmer(func):
        start=time.time()
        func()
        stop=time.time()
        print('run time is %s' %(stop-start))
    timmer(index)

    1.1.5 正确的示范

    import time
    
    def index():
        time.sleep(3)
        print('welecome to index')
    
    def timmer(func):
        # func=index #最原始的index
        def inner():
            start=time.time()
            func() #最原始的index
            stop=time.time()
            print('run time is %s' %(stop-start))
        return inner
    
    index=timmer(index) #index=inner
    # print(f)
    index() #inner()

    1.2 装饰器的修订

    1.2.1 装饰器语法:

    在被装饰对象正上方单独一行写上,@装饰器名

    @deco1
    @deco2
    @deco3
    def foo():
        pass
    foo=deco1(deco2(deco3(foo)))

    1.2.2 改进一:

    import time
    def timmer(func):
        def inner():
            start=time.time()
            res=func()
            stop=time.time()
            print('run time is %s' %(stop-start))
            return res
        return inner
    
    @timmer #index=timmer(index)
    def index():
        time.sleep(1)
        print('welecome to index')
        return 1111
    
    res=index() #res=inner()
    print(res)

    1.2.3 改进二:

    import time
    def timmer(func):
        def inner(*args,**kwargs):
            start=time.time()
            res=func(*args,**kwargs)
            stop=time.time()
            print('run time is %s' %(stop-start))
            return res
        return inner
    
    @timmer #index=timmer(index)
    def index(name):
        time.sleep(1)
        print('welecome %s to index' %name)
        return 1111
    
    res=index('egon') #res=inner('egon')
    print(res)
    
    @timmer #home=timmer(home)
    def home(name):
        print('welcome %s to home page' %name)
    
    home('egon') #inner('egon')

    1.3 有参装饰器

    import time
    
    def auth(func): # func=index
        def inner(*args,**kwargs):
            name=input('name>>: ').strip()
            password=input('password>>: ').strip()
            if name == 'egon' and password == '123':
                print('login successful')
                return func(*args,**kwargs)
            else:
                print('login err')
        return inner
    
    @auth
    def index(name):
        time.sleep(1)
        print('welecome %s to index' %name)
        return 1111
    
    res=index('egon')
    print(res)

    #有参装饰器

    import time
    
     
    
    def auth2(engine='file'):
    
        def auth(func): # func=index
    
            def inner(*args,**kwargs):
    
                if engine == 'file':
    
                    name=input('name>>: ').strip()
    
                    password=input('password>>: ').strip()
    
                    if name == 'egon' and password == '123':
    
                        print('login successful')
    
                        return func(*args,**kwargs)
    
                    else:
    
                        print('login err')
    
                elif engine == 'mysql':
    
                    print('mysql auth')
    
                elif engine == 'ldap':
    
                    print('ldap auth')
    
                else:
    
                    print('engin not exists')
    
            return inner
    
        return auth
    
     
    
    @auth2(engine='mysql') #@auth #index=auth(index) #index=inner
    
    def index(name):
    
        time.sleep(1)
    
        print('welecome %s to index' %name)
    
        return 1111
    
     
    
    res=index('egon') #res=inner('egon')
    
    print(res)
    View Code

    1.4 并列多个装饰器

    import time
    
    def timmer(func):
        def inner(*args,**kwargs):
            start=time.time()
            res=func(*args,**kwargs)
            stop=time.time()
            print('run time is %s' %(stop-start))
            return res
        return inner
    
    def auth2(engine='file'):
        def auth(func): # func=index
            def inner(*args,**kwargs):
                if engine == 'file':
                    name=input('name>>: ').strip()
                    password=input('password>>: ').strip()
                    if name == 'egon' and password == '123':
                        print('login successful')
                        return func(*args,**kwargs)
                    else:
                        print('login err')
                elif engine == 'mysql':
                    print('mysql auth')
                elif engine == 'ldap':
                    print('ldap auth')
                else:
                    print('engin not exists')
            return inner
        return auth
    
    @auth2(engine='file')
    @timmer
    def index(name):
        time.sleep(1)
        print('welecome %s to index' %name)
        return 1111
    
    res=index('egon')
    print(res)

    1.5 wraps补充

    from functools import wraps
    import time
    
    def timmer(func):
        @wraps(func)
        def inner(*args,**kwargs):
            start=time.time()
            res=func(*args,**kwargs)
            stop=time.time()
            print('run time is %s' %(stop-start))
            return res
        # inner.__doc__=func.__doc__
        # inner.__name__=func.__name__
        return inner
    
    @timmer
    def index(name): #index=inner
        '''index 函数。。。。。'''
        time.sleep(1)
        print('welecome %s to index' %name)
        return 1111
    
    # res=index('egon')
    # print(res)
    
    print(help(index))

    1.6 迭代器:

    迭代的工具

    1.6.1 什么是迭代:

    指的是一个重复的过程,每一次重复称为一次迭代,并且每一次重复的结果是下一次重复的初始值
    while True:
    
        print('=====>')
    复制代码
    l=['a','b','c']
    
    count=0
    while count < len(l):
        print(l[count])
        count+=1
    复制代码

      

    1.6.2 为什么要有迭代器?

    对于序列类型:str,list,tuple,可以依赖索引来迭代取值,
    但是对于dict,set,文件,python必须为我们提供一种不依赖于索引的迭代取值的方式-》迭代器
     

    1.6.3 可迭代的对象(下列都是):obj.__iter__

    复制代码
    name='egon'
    l=[1,2,3]
    t=(1,2,3)
    d={'name':'egon','age':18,'sex':'male'}
    s={'a','b','c'}
    f=open('a.txt','w',encoding='utf-8')
    复制代码
    复制代码
    name.__iter__
    l.__iter__
    t.__iter__
    d.__iter__
    s.__iter__
    f.__iter__
    复制代码
     

    1.6.4 迭代器对象(文件是):obj.__iter__,obj.__next__

    f.__iter__
    
    f.__next__

    1.6.5 总结:

    1 可迭代对象不一定是迭代器对象
    2 迭代器对象一定是可迭代的对象
    3 调用obj.__iter__()方法,得到的是迭代器对象(对于迭代器对象,执行__iter__得到的仍然是它本身)
      
    d={'name':'egon','age':18,'sex':'male'}
    
    d_iter=d.__iter__()
    复制代码
    f=open('a.txt','w',encoding='utf-8')
    f_iter=f.__iter__().__iter__().__iter__().__iter__()
    
    
    print(f_iter is f)
    复制代码
    复制代码
    d={'name':'egon','age':18,'sex':'male'}
    d_iter=d.__iter__()
    
    print(d_iter.__next__())
    print(d_iter.__next__())
    print(d_iter.__next__())
    print(d_iter.__next__())
    复制代码

    迭代器d_iter没有值了,就会抛出异常StopIteration

    复制代码
    f=open('a.txt','r',encoding='utf-8')
    print(f.__next__())
    print(f.__next__())
    print(f.__next__())
    print(f.__next__())
    f.close()
    复制代码
    复制代码
    l=['a','b','c']
    
    l_iter=l.__iter__()
    
    print(l_iter.__next__())
    print(l_iter.__next__())
    print(l_iter.__next__())
    print(l_iter.__next__())
    复制代码
    d={'name':'egon','age':18,'sex':'male'}
    d_iter=iter(d) #d_iter=d.__iter__() 
    len(obj) 等同于obj.__len__()

    1.6.6 for循环的本质

    复制代码
    while True:
        try:
            print(next(d_iter)) #print(d_iter.__next__())
        except StopIteration:
            break
    
    print('=>>>')
    print('=>>>')
    print('=>>>')
    print('=>>>')
    复制代码

    for循环详解:

    1、调用in后的obj_iter=obj.__iter__()
    2、k=obj_iter.__next__()
    3、捕捉StopIteration异常,结束迭代
    d={'name':'egon','age':18,'sex':'male'}
    
    for k in d:
    
        print(k)

    1.6.7 总结迭代器的优缺点:

    1.6.71  优点:

    1、提供一种统一的、不依赖于索引的取值方式,为for循环的实现提供了依据
    2、迭代器同一时间在内存中只有一个值——》更节省内存,
     

    1.6.72  缺点:

    1、只能往后取,并且是一次性的
    2、不能统计值的个数,即长度
    复制代码
    l=[1,2,3,4,5,6]
    l[0]
    l[1]
    l[2]
    l[0]
     
    l_iter=l.__iter__()
    
    # print(l_iter)
    print(next(l_iter))
    print(next(l_iter))
    print(next(l_iter))
    print(next(l_iter))
    print(next(l_iter))
    print(next(l_iter))
    print(next(l_iter))
    复制代码
    l_iter=l.__iter__()
    print(next(l_iter))
    print(next(l_iter))
    print(next(l_iter))
    
    print(len(l_iter))
    复制代码

    1.7 生成器

    1.7.1 什么是生成器:

    只要在函数体内出现yield关键字,那么再执行函数就不会执行函数代码,会得到一个结果,该结果就是生成器

    复制代码
    def func():
        print('=====>1')
        yield 1
        print('=====>2')
        yield 2
        print('=====>3')
        yield 3
    
    生成器就是迭代器
    g=func()
    
    res1=next(g)
    print(res1)
    
    
    res2=next(g)
    print(res2)
    
    
    res3=next(g)
    # print(res3)
    复制代码

    1.7.2 yield的功能:

    1、yield为我们提供了一种自定义迭代器对象的方法
    2、yield与return的区别1:yield可以返回多次值 #2:函数暂停与再继续的状态是由yield帮我们保存的 
    复制代码
    obj=range(1,1000000000000000000000000000000000000000000000000000000000000000,2)
    obj_iter=obj.__iter__()
    print(next(obj_iter))
    print(next(obj_iter))
    print(next(obj_iter))
    print(next(obj_iter))
    print(next(obj_iter)) 
    复制代码
    复制代码
    def my_range(start,stop,step=1):
        while start < stop:
            yield start #start=1
            start+=step #start=3
    g=my_range(1,5,2)
    
    print(g)
    
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    for i in my_range(1,5,2):
        print(i)
    复制代码

      

    1.7.3 小练习::tail -f access.log | grep '404'

    复制代码
    import time
    
    def tail(filepath):
        with open(filepath,'rb') as f:
            f.seek(0,2)
            while True:
                line=f.readline()
                if line:
                    yield line
                else:
                    time.sleep(0.05)
    
    def grep(lines,pattern):
        for line in lines:
            line=line.decode('utf-8')
            if pattern in line:
                yield line
    
    lines=grep(tail('access.log'),'404')
    
    for line in lines:
        print(line)
    复制代码

    1.7.4 yield表达式形式的用法(了解知识点)

    复制代码
    def eater(name):
        print('%s ready to eat' %name)
        food_list=[]
        while True:
            food=yield food_list#food=yield='一盆骨头'
            food_list.append(food)
            print('%s start to eat %s' %(name,food))
    
    e=eater('alex')
    #首先初始化:
    print(e.send(None)) # next(e)
    #然后e.send:1 从暂停的位置将值传给yield  2、与next一样
    print(e.send('一桶泔水'))
    print(e.send('一盆骨头'))
    复制代码

    1.8 追加文件

    with open('access.log','a',encoding='utf-8') as f:
        f.write('bbbbb 404
    ')
        f.flush()

    1.9 面向过程编程

    grep -rl 'python' /etc
    补充:os.walk
    复制代码
    import os
    
    g=os.walk(r'D:videopython20期day4a')
    # print(next(g))
    # print(next(g))
    # print(next(g))
    # print(next(g))
    for pardir,_,files in g:
        for file in files:
            abs_path=r'%s\%s' %(pardir,file)
            print(abs_path)

    1.9.1 分析一:

    1.9.11  第一步:拿到一个文件夹下所有的文件的绝对路径

    复制代码
    import os
    
    def search(target): #r'D:videopython20期day4a'
        while True:
            filepath=yield #fllepath=yield=r'D:videopython20期day4a'
            g=os.walk(filepath)
            for pardir, _, files in g:
                for file in files:
                    abs_path = r'%s\%s' % (pardir, file)
                    # print(abs_path)
                    target.send(abs_path)
    
    search(r'D:videopython20期day4a')
    search(r'D:videopython20期day4')
    复制代码

    1.9.12  第二步:打开文件拿到文件对象f

    复制代码
    def opener():
        while True:
            abs_path=yield
            print('opener func--->',abs_path)
    
    target=opener()
    next(target) #target.send('xxxx')
    
    g=search(target)
    next(g)
    g.send(r'D:videopython20期day4a')
    复制代码

    1.9.2 分析二:

    1.9.21  第一步:拿到一个文件夹下所有的文件的绝对路径

    复制代码
    import os
    def init(func):
        def inner(*args,**kwargs):
            g=func(*args,**kwargs)
            next(g)
            return g
        return inner
    
    @init
    def search(target):  # r'D:videopython20期day4a'
        while True:
            filepath = yield
            g = os.walk(filepath)
            for pardir, _, files in g:
                for file in files:
                    abs_path = r'%s\%s' % (pardir, file)
                    #把abs_path传给下一个阶段
                    target.send(abs_path)
    复制代码

    1.9.22  第二步:打开文件拿到文件对象f

    复制代码
    @init
    def opener(target):
        while True:
            abs_path = yield
            with open(abs_path,'rb') as f:
                #把(abs_path,f)传给下一个阶段
                target.send((abs_path,f))
    复制代码

    1.9.23  第三步:读取f的每一行内容

    复制代码
    @init
    def cat(target):
        while True:
            abs_path,f=yield
            for line in f:
                #把(abs_path,line)传给下一个阶段
                res=target.send((abs_path,line))
                #满足某种条件,break掉for循环
                if res:
                    break
    复制代码

    1.9.24  第四步:判断'python' in line

    复制代码
    @init
    def grep(target,pattern):
        pattern = pattern.encode('utf-8')
        res=False
        while True:
            abs_path,line=yield res
            res=False
            if pattern in line:
                #把abs_path传给下一个阶段
                res=True
                target.send(abs_path)
    复制代码

    1.9.25  第五步:打印文件路径

    复制代码
    @init
    def printer():
        while True:
            abs_path=yield
            print('<%s>' %abs_path)
    
    g=search(opener(cat(grep(printer(),'python')))) #'python' in b'xxxxx'
    g.send(r'D:videopython20期day4a')
    复制代码
    面向过程编程:核心是过程二字,过程指的就是解决问题的步骤,即先干什么后干什么,基于该思路编写程序就好比设计一条流水线,是一种机械式的思维方式

    1.9.3 面向过程编程优缺点

    优点:
    复杂的问题流程化、进而简单化
    缺点:
    可扩展性差

    1.10 三元表达式

    复制代码
    def my_max(x,y):
        if x >= y:
            return x
        else:
            return y
    
    x=10
    y=20
    
    # res=x if x >= y else y
    # print(res)
    
    name=input('>>: ').strip()
    
    res='Sb' if name == 'alex' else 'NB'
    print(res) 
    复制代码

    1.11 列表推导式与生成器表达式

    1.11.1 列表推导式

    复制代码
    l=[]
    for i in range(1,11):
        res='egg'+str(i)
        l.append(res)
    print(l)
    
    l=['egg'+str(i) for i in range(1,11)]
    print(l)
    
    l1=['egg'+str(i) for i in range(1,11) if i >= 6]
    print(l1)
    
    l1=[]
    for i in range(1,11):
        if i >= 6:
            l1.append('egg'+str(i))
    复制代码
     

    1.11.2 生成器表达式

    复制代码
    g=('egg'+str(i) for i in range(0,1000000000000000000000000000000000))
    print(g)
    print(next(g))
    print(next(g))
    print(next(g))
    复制代码
     

    1.11.3 练习

    复制代码
    names=['egon','alex_sb','wupeiqi','yuanhao']
    
    names=[name.upper() for name in names]
    print(names)
    
    sbs=[name for name in names if name.endswith('sb')]
    print(sbs)
    
    obj=list('abcdef')
    print(obj)
    
    print(max([1,2,3,4,5]))
    
    g=(i for i in range(10))
    print(max(g))
    print(max(g))
    
    
    with open('a.txt','r',encoding='utf-8') as f:
        l=[]
        for line in f:
            # print(len(line))
            l.append(len(line))
    
        g=(len(line) for line in f)
        res=max(g)
        print(res)
        print(max(len(line) for line in f))
        print(sum(len(line) for line in f)) 
    复制代码

    1.12 递归调用:

    在调用一个函数的过程中,直接或者间接又调用该函数本身,称之为递归调用

    1.12.1 递归必备的两个阶段:

    1、递推

    2、回溯

    复制代码
    import sys
    
    print(sys.getrecursionlimit())
    sys.setrecursionlimit(2000)
    print(sys.getrecursionlimit())
    
    def func(n):
        print('---->',n)
        func(n+1)
    
    func(0)
    
    def bar():
        print('from bar')
        func()
    
    def func():
        print('from func')
        bar()
    func()
     
    age(5) = age(4) + 2
    age(4) = age(3) + 2
    age(3) = age(2) + 2
    age(2) = age(1) + 2
    age(1) = 18
    
    age(n)=age(n-1)+2 # n > 1
    age(1) = 18 #n = 1
     
    def age(n):
        if n == 1:
            return 18
        return age(n-1) + 2
    
    res=age(5)
    print(res)
    
    l=[1,[2,[3,[4,[5,[6,[7,]]]]]]]
    
    
    def func(l):
        for item in l:
            if type(item) is list:
                func(item)
            else:
                print(item)
    
    def func():
        print('===>')
        func()
    func() 
    复制代码

    1.13 二分法(了解的知识点)

    复制代码
    l=[1,2,10,30,33,99,101,200,301,402] #从小到大排列的数字列表
    
    def binary_search(l,num):
        print(l)
        if len(l) == 0:
            print('not exists')
            return
        mid_index=len(l) // 2
        if num > l[mid_index]:
            #往右找
            binary_search(l[mid_index+1:],num)
        elif num < l[mid_index]:
            #往左找
            binary_search(l[0:mid_index],num)
        else:
            print('find it')
    
    # binary_search(l,301)
    binary_search(l,302)
    复制代码

    1.14 匿名函数

    复制代码
    def func(): #func=内存地址
        print('from func')
    
    func()
    func()
    复制代码
    def my_sum(x,y):
    
        return x+y
    print(lambda x,y:x+y)
    
    print((lambda x,y:x+y)(1,2))
    func=lambda x,y:x+y
    # print(func)
    print(func(1,2)) 

    max,min,sorted,map,reduce,filter

    复制代码
    salaries={
        'egon':3000,
        'alex':100000000,
        'wupeiqi':10000,
        'yuanhao':2000
    }
    print(max(salaries))
    复制代码
    复制代码
    s='hello'
    l=[1,2,3]
    g=zip(s,l)
    # print(g)
    print(list(g))
    复制代码
    复制代码
    g=zip(salaries.values(),salaries.keys())
    # print(list(g))
    print(max(g)) 
    def func(k):
        return salaries[k]
    print(max(salaries,key=func)) #key=func('egon')
    
    print(max(salaries,key=lambda k:salaries[k])) #key=func('egon')
    print(min(salaries,key=lambda k:salaries[k])) #key=func('egon')
    复制代码
    sorted
    复制代码
    salaries={
        'egon':3000,
        'alex':100000000,
        'wupeiqi':10000,
        'yuanhao':2000
    }
    print(sorted(salaries,key=lambda k:salaries[k]))
    print(sorted(salaries,key=lambda k:salaries[k],reverse=True)) 
    复制代码
    map,reduce,filter
    复制代码
    names=['alex','wupeiqi','yuanhao']
    l=[]
    for name in names:
        res='%s_SB' %name
        l.append(res)
    print(l)
    
    g=map(lambda name:'%s_SB' %name,names)
    # print(g)
    print(list(g))
    复制代码
    names=['alex_sb','wupeiqi_sb','yuanhao_sb','egon']
    g=filter(lambda x:x.endswith('sb'),names)
    print(g)
    print(list(g))
    复制代码
    from functools import reduce
    print(reduce(lambda x,y:x+y,range(1,101),100))

    1.15 内置函数(了解)

    print(abs(-1))
    print(all([1,'a','b',0]))
    print(all([]))
    print(any([None,False,0,1]))
    print(any([]))
    print(bin(11))
    print(hex(11))
    print(oct(11)) 
    print('xxx'.encode('utf-8'))
    print(bytes('xxx',encoding='utf-8')) 
    print(callable(max))
    复制代码
    print(chr(65))
    # print(chr(90))
    # print(chr(39))
    print(ord('A'))
    print(ord('@'))
    复制代码
    import os
    print(dir(os)) s=set({1,2,3}) s.add(4) print(s)
    s=frozenset({1,2,3}) #不可变集合
    
    print(hash('xxx'))
    l=[1,2,'a',4]
    print(list(reversed(l)))
    s=slice(1,5,2)
    l=['a','b','c','d','e']
    复制代码
    # print(l[1:5:2])
    # print(l[1:5:2])
    
    print(l[s])
    print(vars() is locals())
    obj.__dict__() #vars(obj) 

    1.16 面向对象

    classmethod
    staticmethod
    property
    hasattr
    getattr
    setattr
    delattr
    isinstance
    issubclass
    object
    super

    import
    复制代码
    __import__
    choice=input('>>: ')
    print(choice,type(choice))
    # import 'time'
    m=__import__(choice)
    m.sleep(10) 
    复制代码

    1.17 掌握:

    1.17.1 divmod

    # print(divmod(10011,25))

    1.17.2 enumerate

    复制代码
    l=['a','b','c']
    
    for i in l:
        print(l.index(i),i,)
    
    for i,v in enumerate(l):
        print(i,v)
    复制代码

    1.17.3 eval:

    复制代码
    res=eval('[1,2,3]')
    print(res,type(res))
    
    res=exec('[1,2,3]')
    print(res)
    复制代码

    1.17.4 pow

    res=pow(2,3,3) # (2 ** 3 )%3
    print(res)

    1.17.5 round

    print(round(3.5))  
  • 相关阅读:
    后海日记(8)
    后海日记(8)
    后海日记(7)
    后海日记(7)
    hadoop自己写的最高温度程序源码
    hadoop自己写的最高温度程序源码
    20张图为您讲述磁盘发展史
    20张图为您讲述磁盘发展史
    2017"百度之星"程序设计大赛
    汕头市赛srm1X T3
  • 原文地址:https://www.cnblogs.com/linxidong/p/11190972.html
Copyright © 2020-2023  润新知