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)
  • 相关阅读:
    状态压缩 + 暴力 HDOJ 4770 Lights Against Dudely
    简单几何(推公式) UVA 11646 Athletics Track
    简单几何(四边形形状) UVA 11800 Determine the Shape
    简单几何(求交点) UVA 11437 Triangle Fun
    计算几何模板
    简单几何(相对运动距离最值) UVA 11796 Dog Distance
    简单几何(求划分区域) LA 3263 That Nice Euler Circuit
    覆盖的面积 HDU
    Desert King 最小比率生成树 (好题)
    约会安排 (区间合并)毒瘤题
  • 原文地址:https://www.cnblogs.com/liweijing/p/7228328.html
Copyright © 2011-2022 走看看