zoukankan      html  css  js  c++  java
  • PYTHON_DAY_04

    目录

    一.函数对象

    二.函数的嵌套

    三.函数名称空间与作用域

    四.闭包函数

    五.无惨装饰器简单实现

    六.装饰器的流程分析及修订

    七.有参装饰器的实现及附加多个装饰器流程分析

    八.叠加多个装饰器

    九.迭代器

    十.生成器

    十一.内置函数




    一:函数对象:函数是第一类对象,即函数可以当作数据传递

    1. 可以被引用
    def foo():
        print('from foo')
    
    func=foo
    
    print(foo)
    print(func)
    func()
    

      


    2. 可以当作参数传递
    def foo():
        print('from foo')
    
    def bar(func):
        print(func)
        func()      # 这里在执行foo() 并打印结果
    
    bar(foo)            # 这里执行函数bar() 传入的参数func就是foo地址
    

      

    3. 返回值可以是函数
    def foo():
        print('from foo')
    
    def bar(func):
        return func
    
    f=bar(foo)
    
    print(f)
    
    f()
    

      

    4. 可以当作容器类型的元素
    def foo():
        print('from foo')
    
    dic={'func':foo}    #这里的value-foo就是函数的地址
    
    print(dic['func'])
    
    dic['func']()    

    #利用该特性,优雅的取代多分支的if
    def foo():
    print('foo')

    def bar():
    print('bar')

    dic={
    'foo':foo,
    'bar':bar,
    }
    while True:
    choice=input('>>: ').strip()
    if choice in dic:
    dic[choice]()

    #应用

    def select(sql):
    print('========>select')

    def insert(sql):
    print('========>add')

    def delete(sql):
    print('=======>delete')

    def update(sql):
    print('-=---->update')


    func_dic={
    'select':select,
    'update':update,
    'insert':insert,
    'delete':delete
    }

    def main():
    while True:
    sql = input('>>: ').strip()
    if not sql:continue
    l = sql.split()
    cmd=l[0]
    if cmd in func_dic:
    func_dic[cmd](l)

    main()

    # 这是上面的复杂版
    def main():
    sql = input('>>: ')
    l = sql.split()
    print(l)
    if l[0] == 'select':
    select(l)
    elif l[0] == 'insert':
    insert(l)
    elif l[0] == 'delete':
    delete(l)
    elif l[0] == 'update':
    update(l)
    main()

     


    二:函数的嵌套
    1 函数的嵌套调用
    def max(x,y):
      return x if x > y else y
    
    def max4(a,b,c,d):
      res1=max(a,b)
      res2=max(res1,c)
      res3=max(res2,d)
      return res3
    print(max4(1,2,3,4))
    

      

     2 函数的嵌套定义
    def f1():
            def f2():
                  def f3():
                        print('from f3')
                    f3()
                f2()
    
    f1()
    f3() #报错 f2和f3是被包含在里边的 无法找到
    

      

      

    三 名称空间和作用域:

    A.名称空间定义:名字与值的绑定关系
       3种名称空间:
    1.内置名称空间:随着python解释器启动而产生
      print(sum) #sum就是解释器内置的名称
    2.全局名称空间:文件执行会产生全局名称空间,指的是文件级别定义的名字都会放入该空间
      
    x=1
    def func():
        money=2000
        x=2
        print('func')
    
    func()
    print(x)        # x = 1
    print(money)    # money找不到值
    

      

      3.局部名称空间:调用函数时会产生局部命名空间,只在函数调用时绑定,调用结束解绑定
      
    x=10000
    def func():
        x=1
        def f1():
            pass
    

      



    B.作用域即范围(作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关)
      1.全局作用域( 查看使用 gloabls() ):内置名称空间,全局名称空间
      2.局部作用域( 查看使用 locals() ):局部名称空间

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

    名字查找顺序:局部--》全局--》内置空间
    #  反例  这里的变量就找不到 最终报错
    def func():
        x=2
    
    func()
    
    print(x)  # 所处位置就是全局
    

      

    #全局作用域:全局有效,在任何位置都能被访问到,除非del删掉,否则会一直存活到文件执行完毕

    #局部作用域的名字:局部有效,只能在局部范围调用,只在函数调用时才有效,调用结束就失效
    x=1
    
    def f1():
        print(x)
    
    def foo():
        print(x)
    
    def f(x):
        # x=4
        def f2():
            # x=3
            def f3():
                # x=2
                print(x)
    
            f3()
        f2()
    
    f(4)
    

      





    四:闭包:内部函数包含对外部作用域而非全局作用域的引用

    def counter():
    n=0
    def incr():
    nonlocal n
    x=n
    n+=1
    return x
    return incr

    c=counter()
    print(c())
    print(c())
    print(c())
    print(c.__closure__[0].cell_contents) #查看闭包的元素



    闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
    应用领域:延迟计算
    from urllib.request import urlopen

    def index(url):
    def get():
    return urlopen(url).read()
    return get

    baidu=index('http://www.baidu.com')
    print(baidu().decode('utf-8'))


    五: 装饰器

    1 为何要用装饰器:
    开放封闭原则:对修改封闭,对扩展开放

    2 什么是装饰器
    装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。

    3. 先看简单示范
    import time
        def timmer(func):
            def wrapper(*args,**kwargs):
                start_time=time.time()
                res=func(*args,**kwargs)
                stop_time=time.time()
                print('run time is %s' %(stop_time-start_time))
                return res
            return wrapper
    
        @timmer
        def foo():
            time.sleep(3)
            print('from foo')
        foo()
    

      



    4.
    def auth(driver='file'):
        def auth2(func):
            def wrapper(*args,**kwargs):
                name=input("user: ")
                pwd=input("pwd: ")
    
                if driver == 'file':
                    if name == 'egon' and pwd == '123':
                        print('login successful')
                        res=func(*args,**kwargs)
                        return res
                elif driver == 'ldap':
                    print('ldap')
            return wrapper
        return auth2
    
    @auth(driver='file')
    def foo(name):
        print(name)
    
    foo('egon')
    

      



    5. 装饰器语法:

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

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



    六:迭代器

    迭代的概念:重复的过程称为迭代,每次重复即一次迭代,并且每次迭代的结果是下一次迭代的初始值
    # while True: #只满足重复,因而不是迭代
    # print('====>')

    #迭代
    l=[1,2,3]
    count=0
    while count < len(l): #只满足重复,因而不是迭代
    print('====>',l[count])
    count+=1


    为何要有迭代器?
        --对于没有索引的数据类型,必须提供一种不依赖索引的迭代器
    可迭代的对象?
        --内置__iter__方法的,都是可迭代的对象
       迭代器?
        --执行__iter__方法,得到的结果就是迭代器,迭代器对象有__next__方法  

    l={'a':1,'b':2,'c':3,'d':4,'e':5}
    i=l.__iter__() #等于i=iter(l)

    print(next(i))
    print(next(i))
    print(next(i))

    StopIteration? 异常处理方法
    while True:
        try:                     # 把可能异常的写到try里面
            k=next(i)
            print(k)
        except StopIteration:   # 捕捉异常 异常的话break
            break
    

      

     
    i={'a':1,'b':2,'c':3}.__iter__()
    
    print(i.__next__())
    print(i.__next__())
    print(i.__next__())
    print(i.__next__())      # 这里取道的是字典的key
    
    
    dic={'a':1,'b':2,'c':3}   # 用key来取字典的value
    i=dic.__iter__()
    while True:
        try:
            key=i.__next__()
            print(dic[key])
        except StopIteration:
            break
    

      

    len(s) == s.len()

    s.__iter__ == iter(s)

    dic={'name':'egon','age':18,'height':'180'}  # 迭代字典生成元素为元组
    print(dic.items())
    
    for k in dic.items():     # for循环就相当于一个迭代器 得到的值就是字典的key
        print(k)
     
    # for循环的实现过程如下:
    i=iter(dic)
    while True:
        try:
            k=next(i)
            print(k)
        except StopIteration:
            break
    

      

     
        迭代器的优缺点:
    优点:
    1.提供统一的且不依赖于索引的迭代方式
    2.惰性计算,就迭代器本身节省内存;使用时 next()方法取值
    缺点:
    1.无法获取迭代对象长度
    2.不如序列类型灵活,一次性的,只能往后走,不能往前退
    # 对一个列表
    l=[10000,2,3,4,5]
    
    i=iter(l)
    
    print(i)
    print(next(i))     # 要想使用这个值 就next()方法
    
    
    # 对一个文件 文件本身就是一个好迭代器
    f=open('a.txt',encoding='utf-8')
    
    #for line in f.readlines():      这样的话都读到内存里边 占用内存
    #   print(line)
    
    print(next(f))
    
    for line in f:          # 遍历文件内容使用这个for
        print(line)
    

      

      

      
    七 生成器
      yield功能:
        1.把函数做成迭代器,相当于为函数封装好__iter__和__next__
        2.对比return,可以返回多次值,每次返回都会将函数暂停,下一次next会从上一次暂停的位置继续执行
    # def foo():
    #     return 1
    #     return 2
    #     return 3
    #
    # res=foo()
    # print(res)
    
    
    def foo():
        yield 1
        yield 2
        yield 3
    
    res=foo()
    print(res)
    
    from collections import Iterable,Iterator
    print(isinstance(res,Iterator))
    
    print(next(res))
    print(next(res))
    print(next(res))
    

      


    应用一:计数功能counter
     def counter(n):
            print('start')
            i=0
            while i < n:
                yield i
                i+=1
            print('end')
    
        c=counter(5)
        # print(next(c)) #0
        # print(next(c)) #1
        # print(next(c)) #2
        # print(next(c)) #3
        # print(next(c)) #4
        # print(next(c))  --->没有yield,抛出StopIteration
    
    
        for i in counter(5):
            print(i)
    

      



    应用二: 模拟管道tail -f a.txt |grep 'python'
    # 管道左边的输出结果给到右边的grep 并执行查找‘python’;
    # tail功能是多次返回值,所以这里使用yield实现
    import time def tail(filepath): # filepath 文件路径 with open(filepath,encoding='utf-8') as f: f.seek(0,2) while True: line=f.readline() if line: yield line else: time.sleep(0.5) def grep(pattern,lines): for line in lines: if pattern in line: yield line for i in grep('python',tail('a.txt')): print(i)

      




    
    
    
    

     

  • 相关阅读:
    Educational Codeforces Round 86 (Rated for Div. 2)
    第十六届东南大学大学生程序设计竞赛(春、夏季)
    Codeforces Round #643 (Div. 2)
    [P3384] 【模板】轻重链剖分
    [BJOI2012] 连连看
    [CF1349C] Orac and Game of Life
    Codeforces Round #641 (Div. 2)
    [TJOI2018] 数学计算
    [CF1157D] N Problems During K Days
    [CF1163C1] Power Transmission (Easy Edition)
  • 原文地址:https://www.cnblogs.com/lipingzong/p/6896911.html
Copyright © 2011-2022 走看看