zoukankan      html  css  js  c++  java
  • day4

    1.1   名称空间和作用域:
            名称空间:存放名字的地方,三种名称空间,(之前遗留的问题x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方)
            加载顺序是?
            名字的查找顺序?(在全局无法查看局部的,在局部可以查看全局的)

            # max=1
            def f1():
                # max=2
                def f2():
                    # max=3
                    print(max)
                f2()
            f1()
            print(max)


     作用域即范围
    - 全局范围:全局存活,全局有效
    - 局部范围:临时存活,局部有效
    - 作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,如下
          x=1
          def f1():
              def f2():
                  print(x)
              return f2

          def f3(func):
              x=2
              func()

          f3(f1())


            查看作用域:globals(),locals()

            global
            nonlocal


            LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
            locals 是函数内的名字空间,包括局部变量和形参
            enclosing 外部嵌套函数的名字空间(闭包中常见)
            globals 全局变量,函数定义所在模块的名字空间
            builtins 内置模块的名字空间

    装饰器:

    定义 本质是函数,(装饰其他函数)就是为其他函数添加附加功能

    原则:

    1,不能修改被装饰的函数的源代码

    2,不能修改被装饰的函数的调用方式

    门牌号都没有的时候(没有引用的时候) 内存存的值就会被释放回收  这就是垃圾回收

    del x 删除的是变量名 不是变量值

    函数先定义 再调用

    没定义 调用就会报错

    1.2 高阶函数

    1.2.1 a:把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)但是改变了调用方式

    1.函数接收的参数是一个函数名
      作用:在不修改函数源代码的前提下,为函数添加新功能,
      不足:会改变函数的调用方式

    实例1-1   

    import time
    def bar():
        time.sleep(3)
        print('in the bar')
    def test(func):
        start_time=time.time()
        func()
        stop_time=time.time()
        print('the func run time is %s' %(stop_time -  start_time))
    test(bar)

    1.2.2 b:返回值中包含函数名(不修改函数的调用方式)但不能添加新功能

    函数的返回值是一个函数名
      作用:不修改函数的调用方式
      不足:不能添加新功能

    import time

    def bar():

        time.sleep(3)

        print('in the bar')

    def test2(func):

        print(func)

        return func

    # print(test2(bar))

    bar=test2(bar)#把bar的内存地址传给bar

    bar()  #run bar




    1.3 嵌套函数

    函数的嵌套定义:在一个函数的内部,又定义另外一个函数

    def foo():

        print('in the foo')

        def bar():

            print('in the bar')

        bar()

    foo()

    1.4 闭包函数:

    #1. 定义在函数内部的函数

    #2. 包含对外部作用域名字的引用,而不是对全局作用域名字的引用

    #那么该内部函数就称为闭包函数

     # x=1
    # def  f1():
    #     x=11111111111
    #     def f2():
    #         print(x)
    #     return f2
    # func=f1()
    #
    # x=1000
    # func()
    #
    # def foo():
    #     x=12312312312312312312312312312312312313123
    #     func()
    #
    #
    # foo()


    def deco():
        x=123123123123
        def wrapper():
            print(x)
        return wrapper
    func=deco()

    func()

    第2章 高阶函数+嵌套函数=》》装饰器

    '''import time
    def deco(func):
        start_time=time.time()
        func()
        stop_time=time.time()
        print(stop_time-start_time)
    def test1():
        time.sleep(3)
        print('in the test1')
    def test2():
        time.sleep(3)
        print('in the test2')
    deco(test1)
    deco(test2)
    ''' 
    #利用高阶函数把函数名当做传参的方式
    实现增加了功能没改变源代码 也就是函数的定义没变 但是 改变了原函数的调用方式


    #接下来我们加一层嵌套函数 看能否不改变调用方式能否实现新加功能
    import time
    def timer(func):  #   timer(test1)  func=test1
       
    def deco():
            start_time=time.time()
            func()  #  run test1()
           
    stop_time=time.time()
            print('run time is %s'%(stop_time-start_time))
        return deco
    @timer  # test1=timer(test1)
    def test1():   
       
    time.sleep(3)
        print('in the test1')
    @timer # test2=timer(test2)
    def test2():  
       
    time.sleep(3)
        print('in the test2')
    #print(timer(test1))
    # test1=timer(test1)
    # test2=timer(test2)
    test1()
    test2()
    # deco(test1)
    # deco(test2)

    2.1 装饰器高潮版

    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)

    2.2 装饰器语法:
            被装饰函数的正上方,单独一行
            @deco1
            @deco2
            @deco3
            def foo():
                pass

            foo=deco1(deco2(deco3(foo)))

    2.3 升级版装饰器 支持原函数各类参数的传入

    import time

    from functools import wraps

    def timmer(func):

        @wraps(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():

        '''这是index函数'''

        time.sleep(3)

        print('welcome to index')

        return 123

    print(index.__doc__)

    # print(help(index))

    2.4 补充二:一个函数头顶上可以多个装饰器

    时间装饰器,认证装饰器

    import time

    from functools import wraps

    current_user={'user':None}

    def timmer(func):

        @wraps(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

    def auth(auth_type='file'):

        def deco(func):

            def wrapper(*args, **kwargs):

                if auth_type == 'file':

                    if current_user['user']:

                        return func(*args, **kwargs)

                    name = input('name: ').strip()

                    password = input('password: ').strip()

                    with open('db.txt', encoding='utf-8') as f:

                        user_dic = eval(f.read())

                    if name in user_dic and password == user_dic[name]:

                        res = func(*args, **kwargs)

                        current_user['user'] = name

                        return res

                    else:

                        print('user or password error')

                elif auth_type == 'mysql':

                    print('mysql')

                elif auth_type == 'ldap':

                    print('ldap')

                else:

                    print('not valid auth_type')

            return wrapper

        return deco

    @timmer #index=timmer(wrapper)

    @auth() # @deco #index=deco(index) #wrapper

    def index():

        '''这是index函数'''

        time.sleep(3)

        print('welcome to index')

        return 123

    # print(index.__doc__)

    # print(help(index))

    index()

    2.5 列表生成式

    >>>L = [x * 2 for x in range(10)]

    >>> L

    [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

    >>> g=(x * 2 for x in range(10))

    >>> g

    <generator object <genexpr> at 0x02CC5F80>

    >>> for i in g:

       print(i)

      

    0

    2

    4

    6

    8

    10

    12

    14

    16

    18

    >>> a= [ i for i in range(10)]

    >>> a = map(lambda x:x+1, a)

    >>> a

    <map object at 0x02F66AD0>

    >>> for i in a:print(i)

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    生成器只会在调用的时候才会生成相应的数据

    只记录当前的位置只有一个__next__()方法。next()

    [1,2,3,4,5,6,7,8,9]

    2.6 斐波那契数列

     

    def fib(max):
        n,a,b =0,0,1
        while n< max:
            yield b
            a,b =b,a+b
            n=n+1
        return '---done--' #异常的时候打印的消息
    # fib(10)
    # for n in fib(10):
    #     print(n)
    g=fib(10)
    while True:
        try:
            x = next(g)
            print('g:',x)
        except StopIteration as e:
            print('Generator return value:',e)
            break
    # print(g.__next__())
    # print(g.__next__())
    # print(g.__next__())
    # print(g.__next__())
    # print(g.__next__())
    # print(g.__next__())
    # print(g.__next__())
    next 方法到没数据时会报错

    如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

    2.7 迭代对象

    具有__iter__方法的都是可迭代对象

    说着说可以直接用于for循环的对象统称为可迭代对象 Iterable

    一类是集合数据类型,如list、tuple、dict、set、str等

    一类是generator,包括生成器和带yield的generator function

    可以使用isinstance()判断一个对象是否是Iterable对象:

    >>> from collections import Iterable

    >>> isinstance([],Iterable)

    True

    >>> isinstance({},Iterable)

    True

    >>> isinstance('abc',Iterable)

    True

    >>> isinstance((x for x in range(10)),Iterable)

    True

    >>> isinstance(100,Iterable)

    False

    2.8 迭代器

    1具有__iter__方法

    2可以被next()函数调用并不断返回下一个值的对象

    跌对象转为迭代器的方法


    x='asdfggf'
    x1=iter(x)
    print(next(x1))
    print(next(x1))
    print(next(x1))

     

    而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

    *可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

    可以使用isinstance()判断一个对象是否是Iterator对象:

    >>> from collections import Iterator

    >>> isinstance((x for x in range(10)), Iterator)

    True

    >>> isinstance([], Iterator)

    False

    >>> isinstance({}, Iterator)

    False

    >>> isinstance('abc', Iterator)

    False

    >>> 

    生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。

    把list、dict、str等Iterable变成Iterator可以使用iter()函数:

    >>> isinstance(iter([]), Iterator)

    True

    >>> isinstance(iter({}), Iterator)

    True

    >>> isinstance(iter('abc'), Iterator)

    True

    你可能会问,为什么list、dict、str等数据类型不是Iterator?

    这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

    小结

    凡是可作用于for循环的对象都是Iterable类型;

    凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

    集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

    or甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

    Python的for循环本质上就是通过不断调用next()函数实现的,例如:

    for x in [1, 2, 3, 4, 5]:

        pass

    # 首先获得Iterator对象:
    it = iter([1, 2, 3, 4, 5])
    # 循环:
    while True:
        try:
            # 获得下一个值:
            x = next(it)
        except StopIteration:
            # 遇到StopIteration就退出循环
            break

    2.9 生成器也是迭代器

    只不过他的值不是一下全部在内存的 在是一个一个的生成的,只能前进没法后退 无法知道什么时候结束知道遇到

    #生成器:在函数内部包含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'))

  • 相关阅读:
    【UVA
    Struts2框架学习笔记1
    如何面对这个残酷的世界?——Java模拟
    漫漫学习路——我的大一
    leetcode-36-有效的数独
    leetcode-887-三维形体投影面积
    leetcode-34-在排序数组中查找元素的第一个和最后一个位置
    leetcode-33-搜索旋转排序数组
    leetcode-31-下一个排列
    leetcode-17-电话号码的字母组合
  • 原文地址:https://www.cnblogs.com/lieying6011/p/7248263.html
Copyright © 2011-2022 走看看