day4 函数的包装+装饰器+迭代器

1.函数嵌套:在调用一个函数的过程中,由调用了其他函数

列子:

   def father(name):

     print('from father %s' %name)

     def son():

         print('from son')

         def grandson():

             print('from grandson')

         grandson()

     son()

father("nihao")

2. 闭包函数: 定义在函数内部的函数 包含对外部作用域名字的引用,而不是对全局作用域名字的引用

列子:

  def father(name):

    def son():

        # name='alex'

        print('我爸爸是 [%s]' %name)

        def grandson():

            # name='wupeiqi'

            print('我爷爷是 [%s]' %name)

        grandson()

    son()

father("成龙")

3.名称空间 函数加载顺序:

 3.1名称空间:存放名字的地方,准确的说名称空间是存放名字与变量值绑定关系的地方

 3.2:内置名称空间:在python解释器启动时产生,存放一些python内置的名字

 3.3:全局名称空间:在执行文件时产生,存放文件级别定义的名字

 3.4:局部名称空间:在执行文件的过程中,如果调用了函数,则会产生该函数的局部名称空间,名字在函数调用时生效,在函数调用结束后失败;函数加载顺序:内置---》全局---》局部  ;函数的调用顺序:局部-》全局-》内置

实例:

max=1

def foo():

    max=2

    print(max)

foo()

4.作用域: 全局作用域:全局存活,全局有效:globals()

max=1111111

def f1():

    def f2():

        def f3():

            def f4():

                # print(x)

                print(max)

            f4()

        f3()

    f2()

f1()

4.1 局部作用域:临时存活,局部有效:locals()

例子: 让局部变量在全局生效

x=1

def f1():

    global x

    x=2

f1()

print(x)

例子:局部生效

def func():

    count = 1

    def foo():

        nonlocal count

        count = 12

    foo()

    print(count)

func()

4.2. 作用域关系,在函数定义时就已经固定,于调用位置无关,在调用函数时,必须必须必须回到函数原来定义的位置去找作用域关系

列子:

x=1

def  f1():

    def f2():

        print(x)

    return f2

4.3

5.装饰器

 5.1 开放封闭原则:对扩展是开放的,对修改是封闭;装饰器本身可以是任意可调用对象,被装饰的对象本身也可以是任意可调用对象;

 5.2  不修改被装饰对象的源代;不修改被调用对象的调用方式;为其他函数添加新功能

 5.3 装饰器名,必须写在被装饰对象的正上方,并且是单独一行

列子:

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

6.迭代器:

 6.1:迭代:是一个重复的过程,每一次重复,都是基于上一次的结果而来

 6.2: 可迭代对象iterable:凡是对象下有__iter__方法:对象.__iter__,该对象就是可迭代对

 6.3: 代器对象:可迭代对象执行内置的__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  没有值的情况执行 不会出现爆粗:

迭代器对象的优点;提供了一种统一的(不依赖于索引的)迭代方式 迭代器本身,比起其他数据类型更省内存

迭代器缺点:一次性,只能往后走,不能回退,不如索引取值灵活;无法预知什么时候取值结束,即无法预知长度

7.生成器:

 在函数内部包含yield关键,那么该函数执行的结果是生成器,生成器就是迭代器

 yield的功能:

 把函数的结果做生迭代器(以一种优雅的方式封装好__iter__,__next__) 函数暂停与再继续运行的状态是由yield

例子:

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

原文地址:https://www.cnblogs.com/wangshaojie/p/7230367.html