一、名称空间与作用域
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'))