1. 程式人生 > >裝飾器 叠代器 生成器 面相過程 三元表達式 列表解析 序列化

裝飾器 叠代器 生成器 面相過程 三元表達式 列表解析 序列化

集合 cto 編寫 tor lec 列表解析 http 過程 可擴展性

裝飾器
一 *args,**kwargs
def index(name,age):
print(name,age)

def wrapper(*args,**kwargs):
#args=(1,2,2,3,4,4,5),kwargs={‘x‘:1,‘y‘:2}
index(*args,**kwargs) #index(1,2,2,3,4,4,5,y=2,x=1)

wrapper(‘egon‘,age=18)

二 函數對象:函數可被當做數據傳遞
- 函數可以當做參數傳給另外一個函數
- 一個函數的返回值也可以是一個函數(打破函數的層級限制)
def f1():
def f2():
print(‘f2‘)
return f2
f=f1()
f()

三 名稱空間與作用域
名稱空間
- 分三種
內置名稱空間:python解釋器啟動則生效
全局名稱空間:執行python文件時生效
局部名稱空間:調用函數時,臨時生效,函調用結束則失效

- 加載順序:先內置,再全局,最後有可能產生局部
- 查找名字的順序:先局部,再全局,最後內置

作用:
- 分兩種
全局作用域:全局存活,全局有效
局部作用域:臨時存活,局部有效

強調:作用關系在函數定義階段就已經固定,與調用位置無關

#閉包函數定義:定義在函數內部的函數,特點是:包含對外部作用域而不是對全局作用域名字的引用,該函數就稱之為閉包函數

# x=1
# def outter():
# x=2
# def inner():
# print(x)
# return inner
#
#

# f=outter()
#
# def f1():
# x=1000000000
# f()
#
# f1()

from urllib.request import urlopen

#函數體內內部需要一個變量,有兩種解決方案
#一種是:以參數的形式傳入
def get(url):
return urlopen(url).read()
# get(‘http://www.baidu.com‘)
# get(‘http://www.baidu.com‘)
# get(‘http://www.baidu.com‘)


#另外一種:包起來
# def get(url): #url=‘http://www.baidu.com‘
# # url=‘http://www.baidu.com‘
# def inner():
# return urlopen(url).read()
# return inner
#
# baidu=get(‘http://www.baidu.com‘)
# print(baidu)
# res=baidu()
# baidu()
# baidu()
# baidu()
# baidu()

# def get(x,y):
# def inner():
# print(x,y)
# return inner
#
# baidu=get(‘a‘,‘b‘)
#
# print(baidu.__closure__[0].cell_contents)
# print(baidu.__closure__[1].cell_contents)

x,y=1,2
def get():
y=111111
def inner():
print(x,y)
return inner

baidu=get()
print(baidu.__closure__)

‘‘‘
1、為什麽要用裝飾器:開放封閉原則,對擴展是開放的,對修改是封閉的

2、什麽是裝飾器
- 用來裝飾它人,裝飾器本身可以是任意可調用對象,被裝飾器的對象也可以是任意可調用對象
- 遵循的原則:1、不修改被裝飾對象的源代碼 2、不修改被裝飾對象的調用方式
- 目標是:在遵循原則1和2的前提,為被裝飾器對象添加上新功能


‘‘‘

import time

def timmer(func):
# func=index #最原始的index函數的內存地址
def inner():
start_time=time.time()
func()
stop_time=time.time()
print(‘run time is :[%s]‘ %(stop_time-start_time))
return inner

@timmer #index=timmer(index)
def index():
time.sleep(3)
print(‘welcome to index page‘)


index()


import time
from functools import wraps

def timmer(func):
@wraps(func)
def inner(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print(‘run time is :[%s]‘ %(stop_time-start_time))
return res

return inner

@timmer
def index():
‘‘‘
index function
:return:
‘‘‘
time.sleep(3)
print(‘welcome to index page‘)
return 123

@timmer #home=timmer(home) #home=inner
def home(name):
time.sleep(2)
print(‘welcome %s to home page‘ %name)
return 456

# res=index() # res=inner()
# print(res)
#
# res=home(‘egon‘) #inner(‘egon‘)
# print(res)

# print(index.__doc__)
print(help(index))


有參裝飾器

# import time
# current_status={‘user‘:None,‘login_status‘:False}
#
#
# def auth(func):
# def inner(*args,**kwargs):
# if current_status[‘user‘] and current_status[‘login_status‘]:
# res = func(*args, **kwargs)
# return res
# name=input(‘username>>:‘).strip()
# pwd=input(‘password>>:‘).strip()
# if name == ‘egon‘ and pwd == ‘123‘:
# print(‘login successfull‘)
# current_status[‘user‘]=name
# current_status[‘login_status‘]=True
# res=func(*args,**kwargs)
# return res
# return inner
#
# @auth #index=auth(index)
# def index():
# time.sleep(3)
# print(‘welcome to index page‘)
# return 123
#
# @auth
# def home(name):
# time.sleep(2)
# print(‘welcome %s to home page‘ %name)
# return 456
# index()
# home(‘egon‘)

import time
current_status={‘user‘:None,‘login_status‘:False}
def auth(egine=‘file‘):
# egine=‘file‘
def wrapper(func):
def inner(*args,**kwargs):
if current_status[‘user‘] and current_status[‘login_status‘]:
res = func(*args, **kwargs)
return res

if egine == ‘file‘:
u=‘egon‘
p=‘123‘
elif egine == ‘mysql‘:
print(‘mysql auth‘)
u = ‘egon‘
p = ‘123‘
elif egine == ‘ldap‘:
print(‘ldap auth‘)
else:
pass
name = input(‘username>>:‘).strip()
pwd = input(‘password>>:‘).strip()
if name == u and pwd == p:
print(‘login successfull‘)
current_status[‘user‘] = name
current_status[‘login_status‘] = True
res = func(*args, **kwargs)
return res
return inner
return wrapper
@auth(egine=‘ldap‘) #@wrapper #index=wrapper(index) #index=inner
def index():
time.sleep(3)
print(‘welcome to index page‘)
return 123

index() #inner()

多個裝飾器

import time
current_status={‘user‘:None,‘login_status‘:False}

def timmer(func):
def inner(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()
print(‘run time is :[%s]‘ %(stop_time-start_time))
return res

return inner

def auth(egine=‘file‘):
# egine=‘file‘
def wrapper(func):
def inner(*args,**kwargs):
if current_status[‘user‘] and current_status[‘login_status‘]:
res = func(*args, **kwargs)
return res

if egine == ‘file‘:
u=‘egon‘
p=‘123‘
elif egine == ‘mysql‘:
u = ‘egon‘
p = ‘123‘
elif egine == ‘ldap‘:
u = ‘egon‘
p = ‘123‘
else:
pass
name = input(‘username>>:‘).strip()
pwd = input(‘password>>:‘).strip()
if name == u and pwd == p:
print(‘login successfull‘)
current_status[‘user‘] = name
current_status[‘login_status‘] = True
res = func(*args, **kwargs)
return res
return inner
return wrapper


@timmer
@auth(egine=‘ldap‘) #@wrapper #index=wrapper(timmer_inner)
# @timmer #timmer_inner=timmer(index)
def index():
time.sleep(3)
print(‘welcome to index page‘)
return 123


index() #inner()


叠代器
‘‘‘
1 什麽叫叠代:叠代是一個重復過程,每次重復都是基於上一次的結果來的
2 為什麽要用叠代器?
l=[‘a‘,‘b‘,‘c‘]
n=0
while n < len(l):
print(l[n])
n+=1
- 對於序列類型:字符串,列表,元組,可以使用基於索引的叠代取值方式,而對於沒有索引的類型,如字典,
集合、文件,這種方式不再適用,於是我們必須找出一種能不依賴於索引的取值方式,這就是叠代器

3 可叠代的對象:只要對象內置有__iter__方法,obj.__iter__
4 叠代器對象:對象既內置有__iter__方法,又內置有__next__,如文件對象
註意:可叠代對象不一定是叠代器對象,而叠代器對象一定是可叠代的對象

‘‘‘
#可叠代的對象
# ‘hello‘.__iter__
# [1,2].__iter__
# (1,2).__iter__
# {‘a‘:1}.__iter__
# {1,2,3}.__iter__
#

#既是可叠代對象,又是叠代器對象
# open(‘a.txt‘,‘w‘).__iter__
# open(‘a.txt‘,‘w‘).__next__


# 叠代器對象執行__iter__得到的仍然是它本身
# dic={‘a‘:1,‘b‘:2,‘c‘:3}
# iter_dic=dic.__iter__()
#
# print(iter_dic.__iter__() is iter_dic)

# f=open(‘a.txt‘,‘w‘)
# print(f is f.__iter__())


#叠代器對象的用處
# dic={‘a‘:1,‘b‘:2,‘c‘:3}
# iter_dic=dic.__iter__()


# print(iter_dic.__next__())
# print(next(iter_dic))
# print(next(iter_dic))
# print(next(iter_dic)) #StopIteration


# with open(‘a.txt‘,‘r‘) as f:
# print(next(f))
# print(next(f))
# print(next(f))


# l=[1,2,3,4,5]
# iter_l=l.__iter__()
# print(iter_l)
# print(next(iter_l))
# print(next(iter_l))
# print(next(iter_l))

#基於叠代器對象的叠代取值(不依賴索引)
dic={‘a‘:1,‘b‘:2,‘c‘:3}

iter_dic=dic.__iter__()
obj=range(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)

# list(obj)


# while True:
# try:
# i=next(iter_dic)
# print(i)
# except StopIteration:
# break
#

# for i in dic: #iter_dic=dic.__iter__()
# print(i)


‘‘‘
叠代器的優缺點:
- 優點:
提供了一種統一的叠代取值方式,該方式不再依賴於索引
更節省內存

- 缺點:
無法統計長度
一次性的,只能往後走,不能往前退,無法獲取指定位置的值
‘‘‘

from collections import Iterable,Iterator

print(isinstance(‘hello‘,Iterable))
print(isinstance(‘hello‘,Iterator))


生成器
‘‘‘
定義:只要函數內部出現yield關鍵字,那麽再調用該函數,將不會立即執行函數體代碼,會到到一個結果
該結果就是生成器對象


‘‘‘

#
# def func():
# print(‘===>first‘)
# yield 1
# print(‘===>second‘)
# yield 2
# print(‘====>third‘)
# yield 3
#
#
# g=func()
# print(g)

#生成器本質就是叠代器
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))


# print(next(func()))
# print(next(func()))
# print(next(func()))


# for i in g:
# print(i)
#
# for i in g:
# print(i)
#
# for i in g:
# print(i)

‘‘‘
yield的功能:
- 為我們提供了一種自定義叠代器的方式
- 對比return,可以返回多次值,掛起函數的運行狀態

‘‘‘

#自定義功能,可以生成無窮多個值,因為同一時間在內存中只有一個值
# def my_range(start,stop,step=1):
# while start < stop:
# yield start
# start+=step


# g=my_range(1,5,2) #1 3
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))
# print(next(g))
#
# for i in my_range(1,1000000000000000000000000000000000000000000,step=2):
# print(i)


# 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.2)
#
# def grep(pattern,lines):
# for line in lines:
# line=line.decode(‘utf-8‘)
# if pattern in line:
# yield line
#
# g=grep(‘404‘,tail(‘access.log‘))
# for line in g:
# print(line)


#yield的表達式形式的應用
# def eater(name):
# food_list=[]
# print(‘%s 開動啦‘ %name)
# while True:
# food=yield food_list #food=‘骨頭’
# print(‘%s 開始吃 %s‘ %(name,food))
# food_list.append(food)
#
# g=eater(‘alex‘)

# g.send(None) #next(g)
# print(g.send(‘骨頭‘))
# print(g.send(‘shi‘))

# def f1():
# while True:
# x=yield
# print(x)
#
# g=f1()
# next(g)
# g.send(1)
# g.send(1)
# g.close()
# g.send(1)
# g.send(1)
# g.send(1)


面相過程編程
‘‘‘
強調:面向過程編程絕對不是用函數編程那麽簡單

面向過程的編程思想:核心是過程二字,過程即解決問題的步驟,即先幹什麽再幹什麽
基於該思想去編寫程序就好比在設計一條流水線,是一種機械式的編程思想

優點:復雜的問題流程化,進而簡單化
缺點:可擴展性差


‘‘‘
# import os
# g=os.walk(r‘C:\Users\Administrator\PycharmProjects\19期\day4\a‘)
# for dirname,_,files in g:
# for file in files:
# abs_file_path=r‘%s\%s‘ %(dirname,file)
# print(abs_file_path)


#grep -rl ‘root‘ /etc
import os
def init(func):
def inner(*args,**kwargs):
g=func(*args,**kwargs)
next(g)
return g
return inner

def search(filepath,target): #找到一個文件路徑就往下個階段傳一次
g = os.walk(filepath)
for dirname, _, files in g:
for file in files:
abs_file_path = r‘%s\%s‘ % (dirname, file)
target.send(abs_file_path)

@init
def opener(target):
while True:
abs_file_path=yield
with open(abs_file_path,‘rb‘) as f:
target.send((f,abs_file_path))

@init
def cat(target):
while True:
f,abs_file_path=yield
for line in f:
res=target.send((line,abs_file_path))
if res:
break


@init
def grep(pattern,target):
tag=False
pattern = pattern.encode(‘utf-8‘)
while True:
line,abs_file_path=yield tag
tag=False
if pattern in line:
target.send(abs_file_path)
tag=True


@init
def printer():
while True:
abs_file_path=yield
print(abs_file_path)


search(r‘C:\Users\Administrator\PycharmProjects\19期\day4\a‘,opener(cat(grep(‘你好‘,printer()))))

三元表達式
# name=input(‘>>: ‘)
# if name == ‘alex‘:
# print(‘SB‘)
# else:
# print(‘NB‘)

# name = input(‘>>: ‘)
# print(‘SB‘ if name == ‘alex‘ else ‘NB‘)

def my_max(x,y):
return x if x > y else y




列表解析與生成器表達式
egg_list=[]
for i in range(10):
if i >= 3:
res=‘egg%s‘ %i
egg_list.append(res)

# print(egg_list)
#
#
# l=[‘egg%s‘ %i for i in range(10) if i >= 3]
# print(l)
#
# g=(‘egg%s‘ %i for i in range(10) if i >= 3)
# print(next(g))

# for i in ...:
# if ...:
# for i in ...:
# if ...:
# for ...


names=[‘egon‘,‘alex_sb‘,‘wupeiqi‘,‘yuanhao‘]

names=[name.upper() for name in names if not name.endswith(‘sb‘)]
print(names)

裝飾器 叠代器 生成器 面相過程 三元表達式 列表解析 序列化