第一:命名空间与作用域
命名空间:
局部命名空间:
def foo():
x=1
def func():
pass
全局命名空间:
import time
class ClassName:pass
def foo():pass
内键命名空间:
sum,max,min 等
python加载三个命名空间的顺序:
1.内键命名空间
2.全局命名空间:文件级别的或叫做模块级别的
3.局部命名空间:只有调用函数的时候才会加载,函数调用结束就被释放掉
作用域:
全局作用域:
同时x=1为全局变量 x=1 def func1(): def func2(): def func3(): print(x) func3() func2() func1() 输出结果 1
局部作用域:
x=1 def func1(): def func2(): def func3(): x=100 print(x) func3() func2() func1() 输出结果: 100
第二:闭包
闭包:本质就是一个内部函数
特点:这个内部函数必须包含对外部函数作用域(非全局作用)名字的引用
示例:
def f1(): x=1 y=2 def f2(): print(x) print(y) return f2 func=f1() #func() print(func.__closure__[0].cell_contents)#查看闭包函数的方法 print(func.__closure__[1].cell_contents) #f2为闭包函数 输出结果: 1 2
惰性计算:啥时候用啥时候调用
from urllib.request import urlopen def page(url): def get(): return urlopen(url).read() return get baidu=page('http://www.baidu.com') python=page('http://www.python.org') print(baidu) print(python) 输出结果: <function page.<locals>.get at 0x0000000002DE6BF8> <function page.<locals>.get at 0x0000000002DE6C80> 函数没有执行,已经传了一个参数
第三:装饰器
开放封闭原则
装饰器需要遵循的原则:1,不改变被修饰对象的源代码;2,不改变被修饰对象的调用方式
装饰器是在遵守1和2的前提下,为被装饰的对象添加新功能
装饰器无参基本框架:
#这就是一个实现一个装饰器最基本的架子 def timer(func): def wrapper(): func() return wrapper
装饰器有参基本框架:
def timer(func): def wrapper(*args,**kwargs): func(*args,**kwargs) return wrapper
无参装饰器:
import time def timer(func): #func=最原始的index def warpper(): start_time=time.time() func() end_time=time.time() print('run time is %s' % (end_time - start_time)) return warpper #无参装饰器 @timer #index=timer(index) 此时的index就是warpper def index(): time.sleep(1) print("welcome to index") index()#就是在调用warpper() 原来的index的函数只会输出welcome to index 加上装饰器后; 输出内容为: welcome to index run time is 1.0060575008392334
有参数装饰器:
import time def timer(func): #func=最原始的index def warpper(user): start_time=time.time() func(user) end_time=time.time() print('run time is %s' % (end_time - start_time)) return warpper @timer #index=timer(index) 此时的index就是warpper def home(user): time.sleep(1) print("home %s"% user) home('cy')#就是在调用warpper() 输出结果: home cy run time is 1.0000574588775635
如果传入的参数是关键字类型或者其他的
import time def timer(func): #func=最原始的index def warpper(*args,**kwargs): start_time=time.time() func(*args,**kwargs) end_time=time.time() print('run time is %s' % (end_time - start_time)) return warpper @timer #index=timer(index) 此时的index就是warpper def home(user): time.sleep(1) print("home %s"% user) home('cy')#就是在调用warpper() home(user="zzl") #输出结果: home cy run time is 1.0000574588775635 home zzl run time is 1.0000569820404053
如果原函数有返回值:
import time def timer(func): #func=最原始的index def warpper(*args,**kwargs): start_time=time.time() res=func(*args,**kwargs) end_time=time.time() print('run time is %s' % (end_time - start_time)) return res return warpper @timer #index=timer(index) 此时的index就是warpper def home(user): time.sleep(1) return user + ' is student' res=home('cy')#就是在调用warpper() print(res) #输出结果: run time is 1.0000574588775635 cy is student
装饰器的应用:
无参装饰器的应用:
user_info
name:zzl,passwd:123 name:cyy,passwd:123 name:cy,passwd:123 name:zl,passwd:123
code:
def user_info(): file = open('user_info') data=file.readlines() list_info=[] for i in data: lis=[i.strip()] for s in lis: result = [ele.strip() for ele in s.split(",")] dict_info={} for x in result: res = [ele.strip() for ele in x.split(':')] dict_info.update(dict([res])) list_info.append(dict_info) return list_info user_list=user_info() def help(): print(user_list) current_user={'username':None,'login':False} def auth_deco(func): def wrapper(*args,**kwargs): if current_user['username'] and current_user['login']: res=func(*args,**kwargs) return res username=input('用户名: ').strip() passwd=input('密码: ').strip() for index,user_dic in enumerate(user_list): if username == user_dic['name'] and passwd == user_dic['passwd']: current_user['username']=username current_user['login']=True res=func(*args,**kwargs) return res break else: print('用户名或者密码错误,重新登录') return wrapper help() #无参函数 @auth_deco def home(): print('这里是你家') home()
有参装饰器的应用:
user_info
name:zzl,passwd:123 name:cyy,passwd:123 name:cy,passwd:123 name:zl,passwd:123
code:
def user_info(): file = open('user_info') data=file.readlines() list_info=[] for i in data: lis=[i.strip()] for s in lis: result = [ele.strip() for ele in s.split(",")] dict_info={} for x in result: res = [ele.strip() for ele in x.split(':')] dict_info.update(dict([res])) list_info.append(dict_info) return list_info user_list=user_info() def help(): print(user_list) current_user={'username':None,'login':False} def auth(auth_type='file'): def auth_deco(func): def wrapper(*args,**kwargs): if auth_type == 'file': if current_user['username'] and current_user['login']: res=func(*args,**kwargs) return res username=input('用户名: ').strip() passwd=input('密码: ').strip() for index,user_dic in enumerate(user_list): if username == user_dic['name'] and passwd == user_dic['passwd']: current_user['username']=username current_user['login']=True res=func(*args,**kwargs) return res break else: print('用户名或者密码错误,重新登录') elif auth_type == 'ldap': print('我是ldap') res=func(*args,**kwargs) return res return wrapper return auth_deco #auth(auth_type='file')就是在运行一个函数,然后返回auth_deco,所以@auth(auth_type='file') #就相当于@auth_deco,只不过现在,我们的auth_deco作为一个闭包的应用,外层的包auth给它留了一个auth_type='file'参数 @auth(auth_type='ldap') def index(): print('欢迎来到主页面') @auth(auth_type='file') def home(): print('到家了') index() print(user_list) home()
第四:迭代器
#迭代:更新换代 描述的是一个重复的过程 for while
lis=[4,5,6] i=0 while i<len(lis): print(lis[i]) i+=1 for i in range(len(lis)): print(lis[i]) #输出结果: 4 5 6 4 5 6
针对没有下标的数据类型,我们在想迭代他们的话,就必须提供一种不按照下标取值的方式,python针对这种情况,已经为很多很多的数据类型内置了一个__iter__的方法。
d={'a':1,'b':2} print(d.__iter__()) print([].__iter__()) #输出结果: <dict_keyiterator object at 0x000000000214B728> <list_iterator object at 0x0000000002859400>
数据类型凡是有__iter__方法的都是可迭代的iterable,执行这个方法得到结果就是迭代器iterator,凡是iterator都内置一个__next__方法
d={'a':1,'b':2} i=d.__iter__() print(i) print(i.__next__()) print(i.__next__()) print(i.__next__()) 输出结果: <dict_keyiterator object at 0x000000000220B778> a b print(i.__next__()) StopIteration #这个不是报错是字典没有值了
迭代的认识(针对列表)
l=[1,2,3,4,5] i=iter(l) while l: try: print(next(i)) #i.__next__() except StopIteration as e: break for i in l:#l.__iter__() print(i) #输出结果: 1 2 3 4 5 1 2 3 4 5
迭代器牛逼之处:针对没有下边的数据类型:(字典,文件等)
字典:
dic={'a':1,'b':2,'c':3} d=iter(dic) while d: try: print(dic[next(d)]) except StopIteration: break for i in dic: print(dic[i]) # 输出结果: 1 2 3 1 2 3
文件:
f=open('text','r') print(f) for i in f: #i=f.__iter__() print(i) 输出结果: <_io.TextIOWrapper name='text' mode='r' encoding='cp936'> zzl cyy
for,while之所以能够循环字典,文件,是因为内置用了迭代器的方法
迭代器的优点:
1.提供了一种统一的迭代方式
2.惰性计算,省内存
迭代器的缺点:
1.迭代器看起来就像是一个序列,但是你永远无法预知迭代器的长度
2.不能倒着走,而且是一次性的,只能走一遍
迭代器(Iterator),可迭代的(Iterable)
from collections import Iterator,Iterable print(isinstance('zzl',Iterable)) print(isinstance({},Iterable)) print(isinstance((),Iterable)) print(isinstance({}.__iter__(),Iterator)) f=open('text','r') print(isinstance(f,Iterator)) print(isinstance(f,Iterable)) 输出结果: True True True True True True
第五:生成器
#凡是在函数内部有关键字yield,那么这个函数就是一个生成器。 特别指数在于:函数名+()不再执行,而是得到一个生成器。
from collections import Iterator def foo(): print('我是老大') yield 1 print('我是老二') yield 2 print('我是老三') yield 3 print('我是老四') yield 4 print('我是老五') yield 5 print('我是老六') yield 6 g=foo() #调用以后把它当成迭代器来看 print(g) print(isinstance(g,Iterator)) print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g)) 输出结果: <generator object foo at 0x0000000002160620> True 我是老大 1 我是老二 2 我是老三 3 我是老四 4 我是老五 5 我是老六 6 File "D:/my/python script/untitled/生成器.py", line 30, in <module> print(next(g)) StopIteration #这不是报错,而是没有值了,怎么解决呢,请往下看
def foo(): print('我是老大') yield 1 print('我是老二') yield 2 print('我是老三') yield 3 print('我是老四') yield 4 print('我是老五') yield 5 print('我是老六') yield 6 g=foo() #调用以后把它当成迭代器来看 for i in g: #i=next(g) print(i) 输出结果: 我是老大 1 我是老二 2 我是老三 3 我是老四 4 我是老五 5 我是老六 6
总结:yield的功能是什么?
1.yield是为函数定制__iter__和__next__方法,就是提供一种自定义迭代器的优雅的方法
2.就相当于return,但是可以返回多次
3.生成器本质就是一个数据流,next(生成器)才触发生成器函数的一次执行,下一次next会从上一次暂停的位置继续执行,直到重新遇到一个新的yield。
实现tail -f one.txt | grep ‘cy’的功能:
import time def tail(file_path): with open(file_path) as f: f.seek(0,2) while True: line=f.readline() if not line: time.sleep(0.1) else: yield line def grep(lines,pattern): for line in lines: if pattern in line: yield line pattern_line=grep(tail(r'C:/one.txt'),'cy') for i in pattern_line: print(i) 输出结果: cyy