一、名称空间与作用域

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