zoukankan      html  css  js  c++  java
  • python_day04 函数嵌套 名称空间和作用域 闭包 装饰器 迭代器 生成器 列表解析 三元表达式 生成器表达式

    本节课重要知识点内容如下:

    函数嵌套

    名称空间和作用域

    闭包

    装饰器

    迭代器

    生成器

    列表解析

    三元表达式

    生成器表达式

    1、函数嵌套

    函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数
    函数的嵌套定义:在一个函数的内部,又定义另外一个函数
    def bar():
    print('from nbar')
    def foo():
    print('from foo')
    bar()
    foo()
    def max2(x,y):
    if x > y:
    return x
    else:
    return y
    def max4(a,b,c,d):
    res1=max2(a,b)
    res2=max2(res1,c)
    res3=max2(res2,d)
    return res3
    print(max4(1,2,3,-1))
    def f2():
    print('from f2')
    def f1():
    x=1
    # def f2()
    # print('from f2')
    f2()
    f1()

    名称空间和作用域

    名称空间:存放名字的地方,准确的说名称空间是存放名字与变量值绑定关系的地方
    内置名称空间:在python解释器启动时产生,存放一些python内置的名字
    全局名称空间:在执行文件时产生,存放文件级别定义的名字
    局部名称空间:在执行文件的过程中,如果调用了函数,则会产生该函数的局部名称空间。用来存放该函数内定义的名字,该名字在函数调用时生效,在函数调用结束后失效
    加载顺序:内置---》全局---》局部
    优先掌握一:名字的查找顺序是:局部-》全局-》内置
     x=1
    def func():
    y=2
    def f1():pass
    print
    import os
    class Foo:
    pass
    if x==1:z=3
    del x
    # max=1
    def foo():
    max=2
    # print(max)
    foo()
    print(max)
    x=0
    def f1():
    x=1
    def f2():
    x=2
    def f3():
    x=3
    print(x)
    f3()
    f2()
    print('=f1========',x)
    f1()
    
    
    def func1():
    print('from func1')
    def func1():
    print('=====?>')
    func1()
    作用域:作用的范围,
    全局作用域:全局存活,全局有效:globals()
    局部作用域:临时存活,局部有效:locals()
    global nonlocal掌握
    优先掌握二:作用域关系,在函数定义时就已经固定,于调用位置无关,在调用函数时,必须必须必须回到函数原来定义的位置去找作用域关系
    max=1111111
    def f1():
    def f2():
    def f3():
    def f4():
    # print(x)
    print(max)
    f4()
    f3()
    f2()
    f1()
    x=11111111111111111111111111111111111111111111
    def f1():
    x=1
    y=2
    def f2():pass
    # print(locals())
    print(globals())
    f1()
    print(locals() is globals())
    print(locals())
    print(dir(globals()['__builtins__']))
    # global nonlocal掌握
    x=1
    def f1():
    global x #局部避免改全局名字。#x是不可变类型
    x=2
    f1()
    print(x)
    l=[]
    def f2():
    l.append('f2') #list是可变类型,不需要global关键字也会改全局值
    f2()
    print(l)

    x=0
    def f1():
    # x=1
    def f2():
    # x=2
    def f3():
    # global x
    nonlocal x #nonlocal更改函数的上一级函数名称。nonlocal只能在局部改
    x=3
    f3()
    # print(x)
    f2()
    print(x)
    f1()
    print(x)
    x=1
    def f1():
    def f2():
    print(x)
    return f2
    func=f1()

    print(func)
    func()
    x=10000000
    func()

    def foo(func):
    x=300000000
    func() #f2()
    foo(f1())
    x=10000000000000000000000
    foo(f1())

    闭包

    大前提:作用域关系,在函数定义时就已经固定,于调用位置无关,在调用函数时,必须必须必须回到函数原来定义的位置去找作用域关系闭包函数:
    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()
    
    
    # 闭包函数的应用:惰性计算
    # import requests #pip3 install requests
    def get(url):
    # return requests.get(url).text
    return url
    print(get('https://www.python.org')
    def index(url):
    # url='https://www.python.org'
    def get():
    # return requests.get(url).text
    print(url)
    return get
    python_web=index('https://www.python.org')
    baidu_web=index('https://www.baidu.com')
    python_web()
    baidu_web()
    name='egon'
    def index(url):
    x=1
    y=2
    def wrapper():
    x
    y
    # return requests.get(url).text
    print(name)
    return wrapper
    python_web=index('https://www.python.org')
    print(python_web.__closure__)
    print(python_web.__closure__[0].cell_contents)
    print(python_web.__closure__[1].cell_contents)
    print(python_web.__closure__[2].cell_contents)

     装饰器

    1 开放封闭原则:对扩展是开放的,对修改是封闭
    2 装饰器:装饰它人的工具,
    装饰器本身可以是任意可调用对象,被装饰的对象本身也可以是任意可调用对象
    2.1 装饰器的遵循的原则:1 不修改被装饰对象的源代码 2 不修改被调用对象的调用方式
    2.2 装饰器的目的是:在遵循1和2原则的前提,为其他新功能函数添加
    @装饰器名,必须写在被装饰对象的正上方,并且是单独一行
    补充一:wraps将原函数注释信息等加载到装饰函数中
    补充二:一个函数头顶上可以多个装饰器
    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()
    # 补充一:wraps将原函数注释信息等加载到装饰函数中
    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))
    
    
    # 补充二:一个函数头顶上可以多个装饰器
    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()
    #有返回值的装饰器函数
    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)
    #无参装饰器版本
    current_user={'user':None}
    def auth(func):
    def wrapper(*args,**kwargs):
    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')
    return wrapper
    @auth #index=auth(index) index=wrapper
    def index():
    print('from index')
    index()
    @auth
    def home(name):
    print('welcome %s' %name)
    index() #wrapper()
    home('egon')


    #有参装饰器版本
    current_user={'user':None}
    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
    @auth(auth_type='mysql') #@deco #index=deco(index)
    def index():
    print('from index')
    @auth(auth_type='file')
    def home(name):
    print('welcome %s' %name)
    index() #wrapper()
    home('egon')

    迭代器

    迭代:是一个重复的过程,每一次重复,都是基于上一次的结果而来
    迭代器:
    可迭代对象iterable:凡是对象下有__iter__方法:对象.__iter__,该对象就是可迭代对象
    迭代器对象:可迭代对象执行内置的__iter__方法,得到的结果就是迭代器对象
    什么是迭代器对象:
    1 有__iter__,执行得到仍然是迭代本身
    2 有__next__
    迭代器对象的优点
    1:提供了一种统一的(不依赖于索引的)迭代方式
    2:迭代器本身,比起其他数据类型更省内存
    迭代器对象的缺点
    1:一次性,只能往后走,不能回退,不如索引取值灵活
    2:无法预知什么时候取值结束,即无法预知长度
    补充:判断可迭代对象与迭代器对象(了解)
    print(isinstance(set1,Iterable))
    print(isinstance(f,Iterable))
    while True: #单纯的重复
    print('你瞅啥')
    l=['a','b','c','d']
    count=0
    while count < len(l):
    print(l[count])
    count+=1
    dic={'name':'egon','sex':'m',"age":18} #上述按照索引的取值方式,不适于没有索引的数据类型
    #可迭代对象
    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
    #不依赖于索引的取值方式
    l=['a','b','c','d']
    dic={'name':'egon','sex':'m',"age":18}
    iter_l=iter(l)
    iter_dic=iter(dic)
    while True:
    try:
    # print(next(iter_l))
    k=next(iter_dic)
    print(k,dic[k])
    except StopIteration:
    break

    l=['a','b','c','d']
    i=iter(l)
    dic={'a':1,'b':2}
    x=dic.keys()
    print(x)
    i=x.__iter__()
    with open('a.txt') as f:
    print(next(f))
    print(next(f))
    print(next(f))
    f.read()
    #for循环原理
    l=['a','b','c','d']
    for item in l: #iter_l=l.__iter__()
    print(item)
    for item in {1,2,3,4}:
    print(item)
    with open('a.txt') as f:
    # for line in f: #i=f.__iter__()
    # print(line)
    print(f is f.__iter__())
    #补充:判断可迭代对象与迭代器对象(了解)
    from collections import Iterable,Iterator
    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('a.txt')
    print(isinstance(s,Iterable))
    print(isinstance(l,Iterable))
    print(isinstance(t,Iterable))
    print(isinstance(dic,Iterable))
    print(isinstance(set1,Iterable))
    print(isinstance(f,Iterable))
    print(isinstance(s,Iterator))
    print(isinstance(l,Iterator))
    print(isinstance(t,Iterator))
    print(isinstance(dic,Iterator))
    print(isinstance(set1,Iterator))
    print(isinstance(f,Iterator))

    生成器

    生成器:在函数内部包含yield关键,那么该函数执行的结果是生成器
    生成器就是迭代器
    yield的功能:
    1 把函数的结果做生迭代器(以一种优雅的方式封装好__iter__,__next__)
    2 函数暂停与再继续运行的状态是由yield
    raise StopIteration #产生一个异常
    yield与return的比较?
    相同:都有返回值的功能
    不同:return只能返回一次值,而yield可以返回多次值
    生成器表达式
    def func():
    print('first')
    yield 11111111
    print('second')
    yield 2222222
    print('third')
    yield 33333333
    print('fourth')
    g=func()
    print(g) #generator
    from collections import Iterator
    print(isinstance(g,Iterator))
    print(next(g))
    print('======>')
    print(next(g))
    print('======>')
    print(next(g))
    print('======>')
    print(next(g)) #StopIteration
    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)
    # 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'))
    #追加内容
    with open('access.log','a') as f:
    f.write('22222error ')

    列表解析

    l=['egg%s' %i for i in range(10)  if i >=5]
    l=[]
    for i in range(10):
    if i >=5:
    l.append('egg%s' %i)
    print(l)
    # 列表解析
    for i0 in ...:
    if 条件1:
    for i1 in ...:
    if 条件2:
    for i2 in ...:
    if 条件3:
    pass
    l=['egg%s' %i for i in range(10) if i >=5]
    print(l)

    nums=[1,2,3,4,5,6]
    nums_new=[item**2 for item in nums if item > 3]
    print(nums_new)

    nums_new=[]
    for item in nums:
    nums_new.append(item**2)
    print(nums_new)

    names=['alex_sb','wupeiqi_sb','egon','yuanhao_sb']
    names_new=[name for name in names if name.endswith('sb')]
    print(names_new)

    三元表达式

    res=x if x > 3 else 'no'
    def foo(x):
    if x > 3:
    return 'ok'
    else:
    return 'no'
    x=10
    res=x if x > 3 else 'no'
    print(res)

    def max2(x,y):
    return x if x > y else y
    print(max2(1,3))

    name='egon'
    print('SB' if name == 'alex' else 'shuai')

    生成器表达式

    #生成器表达式
    g=('egg%s' %i for i in range(1000))
    print(g)
    print(next(g))
    print(next(g))
    print(next(g)

    with open('a.txt',encoding='utf-8') as f:
    # res=max((len(line) for line in f))
    res=max(len(line) for line in f)
    print(res)
    print(max([1,2,3,4,5,6]))
    #生成器应用
    res=sum(i for i in range(3))
    print(res)

    with open('db.txt',encoding='utf-8') as f:
    l=(float(line.split()[1])*int(line.split()[2]) for line in f)
    print(sum(l))
    
    
    # [{'name': 'apple', 'price': 333, 'count': 3}, ]
    with open('db.txt',encoding='utf-8') as f:
    info=[{'name':line.split()[0],
    'price':float(line.split()[1]),
    'count':int(line.split()[2])} for line in f if float(line.split()[1]) >= 30000]
    print(info)
  • 相关阅读:
    【已解决】Makefile执行过程中出错:make: *** No rule to make target ` ‘, needed by xxx. Stop(转载)
    eclipse导入工程报Invalid project description(转载)
    基于Linux的v4l2视频架构驱动编写(转载)
    在eclipse中如何在大量项目中查找指定文件(转载)
    Ubuntu下FileZilla的安装(转载)
    创建 /dev/video0 节点 (转载)
    python函数-迭代器&生成器
    前端第三篇---前端基础之JavaScript
    前端第二篇---前端基础之CSS
    块级元素和行内元素使用心得汇总
  • 原文地址:https://www.cnblogs.com/liweijing/p/7228328.html
Copyright © 2011-2022 走看看