• 末学者笔记--Python函数二玄


    Python函数:二玄

    一.名称空间和作用域                                                             

    1.内置名称空间:

    python启动时就有)python解释器内置的名字,print,max,min

    Print其实是python内置的函数。

    1. 全局名称空间:

    (执行python文件时启动)定投定义的变量,如在Python界面直接定义的变量:a = 3 ,即为全局变量。

     

    2. 局部名称空间:

    (调用函数时启动,调用结束失效)函数内部定义的变量

    如:

    在函数内的定义的一个变量即为局部变量。

     

    总结

    三者的加载顺序

            内置--->全局--->局部

        

            三者的访问顺序

            局部--->全局--->内置

     

    二.装饰器                                                                         

    1.什么是装饰器?

    在不修改源代码和调用方式的基础上给函数增加新的功能,即为装饰器,多个装饰器可以装饰在同一个函数上

     

    2.无参装饰器

     

    def add(he):
        def wrpper():
            he()  #he=message
            print('这是一个笑话')

        return wrpper
    @add     #@add达到的效果:message=add(message)=wrpper 这是其id内存地址
    def message():

        print('有2棵树就有4只鸟')
    message()

    》》

    2棵树就有4只鸟

    这是一个笑话

    》》

     

    3.有参装饰器:

    def add(he):
        def wrpper(x,y):
            he(x,y)  #he=message
            print('这是一个笑话')

        return wrpper
    @add   #message=add(message)=wrpper 这是其id内存地址
    def message(x,y):

        print('有%s棵树就有%s只鸟' % (x,y))
    message(2,4)

    》》

    2棵树就有4只鸟

    这是一个笑话

    》》

    4.带参数的装饰器:

     

    def default_engine(engine=None):
        def auth(func):
            def deco(*args, **kwargs):
                user = input('user:')
                password = input('password:')
                if engine == 'mysql':
                    if user == 'root' and password == 'root':
                        res = func(*args, **kwargs)
                        return res
                    else:
                        print('用户名或密码错误')
                else:
                    print('没有这个引擎')
            return deco
        return auth

    @default_engine(engine='mysql')
    def index():
        print('welcome to home page')
    # res = default_engine(engine='mysql')
    # index = res(index)
    index()

    三.迭代器                                                                    

    1.什么是迭代器?

       迭代是一个重复的过程,即每一次重复为一次迭代,并且每次迭代的结果都是下一次迭代的初始值

    while True:    #只是单纯的重复,因此不是迭代

        print('===>')

     

    l = [1,2,3]

    count = 0

    while  count<len(l):   #首先是重复动作,其次上一次的结果是下一次的初始值,因此,是迭代

        print(l[count])

        count+=1

     

    2.为什么要有迭代器?可迭代对象迭代器对象

    (1)为何要有迭代器?

    对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器

     

    2什么是可迭代对象?

    可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,如下:

    'world'.__iter__

    (4,5,6).__iter__

    [1,2,3].__iter__

    {'a':1}.__iter__

    {'a','b'}.__iter__

    open('a.txt').__iter__

     

    3什么是迭代器对象?

    可迭代对象执行obj.__iter__()得到的结果就是迭代器对象

    而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象

     

    4文件类型是迭代器对象

    open('a.txt').__iter__()

    open('a.txt').__next__()

     

    5总结:

    迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象

     

    四:生成器                                                               

    1.什么是生成器?

    只要函数里有yield关键字,那么函数名()得到的结果就是生成器,并且不会执行函数内部代码

    # 生成器就是迭代器

     

    2.returnyield区别:

        # return只能返回一个值

    # yield可以返回多个值,同一时间只能存储一个值;缺点:没有索引,不能后退取值

     

    return的方式
    def test():
        l = []
        for i in range(10):
            l.append(i)
        return l
    print(test()[4])

     

    Yield方式:

    def test():
        l = ['a','b','c']
        for i in l:
            yield i
    for i in test():
        print(i)

    》》

    a

    b

    c

    》》

     

    【特殊】:

    def test():
        l = ['a','b','c']
        for i in l:
            yield i
    print(next(test()))
    print(next(test()))
    print(next(test()))


    print('==============')


    a = test()  #生成器的算法是:每次直接调用如‘print(next(test()))’,都会刷新迭代数位,即从新取值;赋予给一个变量即可免去算法刷新
    print(next(a))

    print(next(a))
    print(next(a))

    》》

    a

    a

    a

    ==============

    a

    b

    c

    》》

     

    五:匿名函数                                                                           

    1. 定义

    匿名函数的定义:lambda,自带return

    匿名函数通常只调用一次,之后不再使用。

     

    2. 格式:

    lambda x,y: x+y     

    其整体是一个函数内存地址,即(lambda x,y: x+y)(ab)为调用函数

    直接输出:

    print((lambda x,y:x+y)(1,2))

    》》

    3

    》》

    3.lambda的使用场景

    #max  sorted  map  filter  zip】

    info = {
        'li':2000,
        'zhao':35000,
        'wu': 34000,
        'du': 40000
    }

    1# max:取最大值

    print(max(info,key=lambda k:info[k]))   #max 本身做了一个循环比较;

    》》

    du

    》》

    解释:max本身开始循环info字典的key值,将key值赋予给匿名函数的参数‘k’,匿名函数代入‘k’值后返回info字典的对应value值,此时max再进行大小比较,取出最大value值,但输出的是其对应的key值。

     

    2# sorted:排序

    print(sorted(info,key=lambda k:info[k]))
    print(sorted(info,key=lambda k:info[k],reverse=True))   #反向排序

    》》

    ['li', 'wu', 'zhao', 'du']

    ['du', 'zhao', 'wu', 'li']

    》》

    原理:同max的原理,

     

    3# map:映射

    names = ['zhao','wu','du']

    #想在每个元素后面加一个‘nb’,通常如下:
    l1 = []
    for name in names:
        res = '%s_nb' % name
        l1.append(res)
    print(l1)

    》》

    ['zhao_nb', 'wu_nb', 'du_nb']

    》》

     

    但使用匿名函数更简单:

    print(list(map(lambda name:'%s_nb' % name,names)))

    结果一样,同理map映射也是变成迭代器对象

    res = map(lambda name:'%s_nb' % name,names)
    print(res.__next__())
    print(res.__next__())
    print(res.__next__())

    》》

    zhao_nb

    wu_nb

    du_nb

    》》

     

    4# filter:过滤

    names = ['zhao_nb', 'wu_nb', 'du_nb','li']
    print(list(filter(lambda i: i.endswith('nb'),names)))
    print(list(filter(lambda i: not i.endswith('nb'),names)))

    》》

    ['zhao_nb', 'wu_nb', 'du_nb']

    ['li']

    》》

     

    【补】 # zip:拉链

    l1 = [1,2,3,4]
    l2 = ['a','b','c']
    print(list(zip(l1,l2)))
    res = zip(l1,l2)    #很明显zip后是个迭代器对象
    print(next(res))
    print(next(res))
    print(next(res))

    》》

    [(1, 'a'), (2, 'b'), (3, 'c')]

    (1, 'a')

    (2, 'b')

    (3, 'c')

    》》

    将列表对应元素连成一个元组,元素个数不对应则去除多余元素。

    =======================================分割线===================================

  • 相关阅读:
    .net core webapi 前后端开发分离后的配置和部署
    403
    Visual Studio提示“无法启动IIS Express Web服务器”的解决方法
    一件能让人没脸见人的事
    过程 sp_addextendedproperty, 对象无效。不允许有扩展属性,或对象不存在。
    处理程序“ExtensionlessUrlHandler-Integrated-4.0”在其模块列表中有一个错误模块“ManagedPipelineHandler”
    阿里ECS配置MSSQL远程连接的坑
    .Net Webapi SignalR与微信小程序的交互
    Entity Framework 异常: 'OFFSET' 附近有语法错误。 在 FETCH 语句中选项 NEXT 的用法无效。
    postgresql 表继承
  • 原文地址:https://www.cnblogs.com/feige2L/p/11023231.html
Copyright © 2020-2023  润新知