一、名称空间与作用域

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