函数进阶篇

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\n')
    f.flush()

 

1.9 面向过程编程

grep -rl 'python' /etc
补充:os.walk
复制代码
import os

g=os.walk(r'D:\video\python20期\day4\a')
# 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:\video\python20期\day4\a'
    while True:
        filepath=yield #fllepath=yield=r'D:\video\python20期\day4\a'
        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:\video\python20期\day4\a')
search(r'D:\video\python20期\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:\video\python20期\day4\a')
复制代码

 

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:\video\python20期\day4\a'
    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:\video\python20期\day4\a')
复制代码

 

面向过程编程:核心是过程二字,过程指的就是解决问题的步骤,即先干什么后干什么,基于该思路编写程序就好比设计一条流水线,是一种机械式的思维方式

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))  

 

posted @ 2019-07-15 19:40  Zeus-Lin  阅读(160)  评论(0编辑  收藏  举报