一、名称空间与作用域
1,名称空间分为三部分,名称空间通俗来说就是变量
局部名称空间:如函数或类内的局部名称空间,调用优先级最高
全局名称空间:在全局定义的名称空间如,函数、类、变量等,调用优先级为中。
内置名称空间:python自带的,在任何地方都可以调用,但是优先级最低。
二、闭包函数
如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。
举例说明闭包函数
#闭包函数:
#1. 定义在函数内部的函数
#2. 包含对外部作用域名字的引用,而不是对全局作用域名字的引用
#那么该内部函数就称为闭包函数,
x=1
def f1(): x=11111111111 def f2(): print(x) return f2 func=f1() #他不会改变外部x=1的结果
三、装饰器
#1 开放封闭原则:对扩展是开放的,对修改是封闭
#2 装饰器:装饰它人的工具,
#装饰器本身可以是任意可调用对象,被装饰的对象本身也可以是任意可调用对象
#2.1 装饰器的遵循的原则:1 不修改被装饰对象的源代码 2 不修改被调用对象的调用方式
#2.2 装饰器的目的是:在遵循1和2原则的前提,为其他新功能函数添加
内裤可以用来遮羞,但是到了冬天它没法为我们防风御寒,聪明的人们发明了长裤,有了长裤后宝宝再也不冷了,装饰器就像我们这里说的长裤,在不影响内裤作用的前提下,给我们的身子提供了保暖的功效。
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
import time def timmer(func): # func=index def wrapper(): start=time.time() func() stop=time.time() print('run time is %s' %(stop-start)) return wrapper @timmer # index=timmer(index) def index(): time.sleep(3) print('welcome to index') @timmer # home=timmer(home) def home(): time.sleep(2) print('welcome to home page') index() home()
四、有参装饰器
上面说的的是默认没有参数的装饰器,假如有参数会报错的,
下面的例子说明有参数的装饰器
import time def timmer(func): def wrapper(*args,**kwargs): start=time.time() res=func(*args,**kwargs) stop=time.time() print('run time is %s' %(stop-start)) return res return wrapper @timmer # index=timmer(index) def index(): time.sleep(3) print('welcome to index') return 123 @timmer # home=timmer(home) def home(name): time.sleep(2) print('welcome %s to home page' %name) # res=index() #res=wrapper() # print(res) res1=home('egon') #wrapper('egon') print(res1)
五、可迭代对象与迭代对象
迭代的定义:给定一个list或者tuple,通过for循环来遍历这个list或者tuple、这种遍历就是迭代(iteration)。只要是可迭代的对象都可以进行迭代、怎么判断一个对象是否是可迭代的对象呢?可以用collections模块里面的iterable包的isinstance函数进行判断。
#迭代器: #可迭代对象iterable:凡是对象下有__iter__方法:对象.__iter__,该对象就是可迭代对象
s='hello'
l=['a','b','c','d']
t=('a','b','c','d')
dic={'name':'egon','sex':'m',"age":18}
set1={1,2,3}
f=open('db.txt')
s.__iter__()
l.__iter__()
t.__iter__()
dic.__iter__()
set1.__iter__()
f.__iter__()
#迭代器对象:可迭代对象执行内置的__iter__方法,得到的结果就是迭代器对象
dic={'name':'egon','sex':'m',"age":18}
i=dic.__iter__()
# print(i) #iterator迭代器
# i.__next__() #next(i)
print(next(i))
print(next(i))
print(next(i))
print(next(i)) #StopIteration
l=['a','b','c','d']
i=l.__iter__()
print(next(i))
print(next(i))
print(next(i))
print(next(i))
print(next(i)) #StopIteration
#什么是迭代器对象:
#1 有__iter__,执行得到仍然是迭代本身
#2 有__next__
#迭代器对象的优点
#1:提供了一种统一的(不依赖于索引的)迭代方式
#2:迭代器本身,比起其他数据类型更省内存
六、生成器
#生成器:在函数内部包含yield关键,那么该函数执行的结果是生成器
#生成器就是迭代器
#yield的功能:
# 1 把函数的结果做生迭代器(以一种优雅的方式封装好__iter__,__next__)
# 2 函数暂停与再继续运行的状态是由yield
def func(): print('first') yield 11111111 print('second') yield 2222222 print('third') yield 33333333 print('fourth') g=func() print(g) from collections import Iterator print(isinstance(g,Iterator)) print(next(g)) print('======>') print(next(g)) print('======>') print(next(g)) print('======>') print(next(g)) for i in g: #i=iter(g) print(i) def func(n): print('我开动啦') while True: yield n n+=1 g=func(0) # print(next(g)) # print(next(g)) # print(next(g)) for i in g: print(i) for i in range(10000): print(i) def my_range(start,stop): while True: if start == stop: raise StopIteration yield start #2 start+=1 #3 g=my_range(1,3) # print(next(g)) print(next(g)) print(next(g)) for i in my_range(1,3): print(i)
#yield与return的比较?
#相同:都有返回值的功能
#不同:return只能返回一次值,而yield可以返回多次值
# python3 tail.py -f access.log | grep 'error'
import time
def tail(filepath):
with open(filepath, 'r') 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:
if pattern in line:
print(line,end='')
grep('error',tail('access.log'))