美文网首页
python第三章函数进阶

python第三章函数进阶

作者: 牛奶加醋 | 来源:发表于2018-06-22 23:30 被阅读6次

    函数进阶

    命名空间

    又名name space, 顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方

    名称空间共3种,分别如下

    • locals: 是函数内的名称空间,包括局部变量和形参
    • globals: 全局变量,函数定义所在模块的名字空间
    • builtins: 内置模块的名字空间

    不同变量的作用域不同就是由这个变量所在的命名空间决定的。

    作用域即范围

    • 全局范围:全局存活,全局有效
    • 局部范围:临时存活,局部有效

    查看作用域方法 globals(),locals()

    LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> builtins

    • locals 是函数内的名字空间,包括局部变量和形参
    • enclosing 外部嵌套函数的名字空间
    • globals 全局变量,函数定义所在模块的名字空间
    • builtins 内置模块的名字空间

    闭包

    关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数)。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。

    也就是说,内部函数会在外部函数返回后被执行。而当这个内部函数执行时,它仍然必需访问其外部函数的局部变量、参数以及其他内部函数。这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会受到内部函数的影响。

    闭包的意义:

    返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域

    装饰器!!!

    利用闭包实现装饰器的功能.

    软件开发中的一个原则“开放-封闭”原则,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即:

    • 封闭:已实现的功能代码块不应该被修改
    • 开放:对现有功能的扩展开放

    被装饰的函数如果有参数,

    带参数装饰器

    #_*_coding:utf-8_*_
    user_status = False #用户登录了就把这个改成True
    
    def login(auth_type): #把要执行的模块从这里传进来
        def auth(func):
            def inner(*args,**kwargs):#再定义一层函数
                if auth_type == "qq":
                    _username = "alex" #假装这是DB里存的用户信息
                    _password = "abc!23" #假装这是DB里存的用户信息
                    global user_status
    
                    if user_status == False:
                        username = input("user:")
                        password = input("pasword:")
    
                        if username == _username and password == _password:
                            print("welcome login....")
                            user_status = True
                        else:
                            print("wrong username or password!")
    
                    if user_status == True:
                        return func(*args,**kwargs) # 看这里看这里,只要验证通过了,就调用相应功能
                else:
                    print("only support qq ")
            return inner #用户调用login时,只会返回inner的内存地址,下次再调用时加上()才会执行inner函数
    
        return auth
    
    def home():
        print("---首页----")
    
    @login('qq')
    def america():
        #login() #执行前加上验证
        print("----欧美专区----")
    
    def japan():
        print("----日韩专区----")
    
    @login('weibo')
    def henan(style):
        '''
        :param style: 喜欢看什么类型的,就传进来
        :return:
        '''
        #login() #执行前加上验证
        print("----河南专区----")
    
    home()
    # america = login(america) #你在这里相当于把america这个函数替换了
    #henan = login(henan)
    
    # #那用户调用时依然写
    america()
    
    # henan("3p")
    

    生成器

    列表生成式

    >>> a = [i+1 for i in range(10)]
    >>> a
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    

    在Python中,这种一边循环一边计算的机制,称为生成器:generator。

    要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

    >>> L = [x * x for x in range(10)]
    >>> L
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    >>> g = (x * x for x in range(10))
    >>> g
    <generator object <genexpr> at 0x1022ef630>
    

    generator保存的是算法,每次调用next(g)就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

    创建了一个generator后,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration的错误。

    生成器的创建方式

    1. 列表生成式
    2. 函数
    • yield vs retrun
    • return 返回 并终止function
    • yield 返回数据,并冻结当前的执行过程...
    • next唤醒冻结的函数执行过程,继续执行,直到遇到下一个yield
    • 函数有了yield之后
      • 函数名加()就变成了一个生成器
      • return在生成器里,代表生成器的终止,直接报错(生成器用next()调用最后一次结束后就会报错,用for循环就不会)
    • send的作用
      • 唤醒并继续执行
      • 发送一个信息到生成器内部

    迭代器

    迭代 = 循环

    可以直接作用于for循环的数据类型有以下几种:

    一类是集合数据类型,如listtupledictsetstr等;

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

    这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

    可以使用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
    

    而生成器不但可以作用于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对象,但listdictstr虽然是Iterable,却不是Iterator

    listdictstrIterable变成Iterator可以使用iter()函数:

    >>> isinstance(iter([]), Iterator)
    True
    >>> isinstance(iter('abc'), Iterator)
    True
    

    小结

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

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

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

    在Python中,代码不是越多越好,而是越少越好。代码不是越复杂越好,而是越简单越好。

    基于这一思想,我们来介绍Python中非常有用的高级特性,1行代码能实现的功能,决不写5行代码。请始终牢记,代码越少,开发效率越高。

    作业

    员工信息增删改查

    现要求你写一个简单的员工信息增删改查程序,需求如下:

    [图片上传失败...(image-3bc268-1529681401554)]

    当然此表你在文件存储时可以这样表示

    1,Alex Li,22,13651054608,IT,2013-04-01
    2,Jack Wang,28,13451024608,HR,2015-01-07
    3,Rain Wang,21,13451054608,IT,2017-04-01
    4,Mack Qiao,44,15653354208,Sales,2016-02-01
    5,Rachel Chen,23,13351024606,IT,2013-03-16
    6,Eric Liu,19,18531054602,Marketing,2012-12-01
    7,Chao Zhang,21,13235324334,Administration,2011-08-08
    8,Kevin Chen,22,13151054603,Sales,2013-04-01
    9,Shit Wen,20,13351024602,IT,2017-07-03
    10,Shanshan Du,26,13698424612,Operation,2017-07-02
    

    1.可进行模糊查询,语法至少支持下面3种查询语法:

    find name,age from staff_table where age > 22
    
    find * from staff_table where dept = "IT"
    
    find * from staff_table where enroll_date like "2013"
    

    2.可创建新员工纪录,以phone做唯一键(即不允许表里有手机号重复的情况),staff_id需自增

    语法: add staff_table Alex Li,25,134435344,IT,2015-10-29
    

    3.可删除指定员工信息纪录,输入员工id,即可删除

    语法: del from staff where  id=3
    

    4.可修改员工信息,语法如下:

    UPDATE staff_table SET dept="Market" WHERE  dept = "IT" 把所有dept=IT的纪录的dept改成Market
    UPDATE staff_table SET age=25 WHERE  name = "Alex Li"  把name=Alex Li的纪录的年龄改成25
    

    5.以上每条语名执行完毕后,要显示这条语句影响了多少条纪录。 比如查询语句 就显示 查询出了多少条、修改语句就显示修改了多少条等。

    注意:以上需求,要充分使用函数,请尽你的最大限度来减少重复代码!

    
    

    相关文章

      网友评论

          本文标题:python第三章函数进阶

          本文链接:https://www.haomeiwen.com/subject/jvglyftx.html