• Python之路-4


    1.1 装饰器、生成器、迭代器、调用函数、内置函数

    1.1.1 装饰器

    装饰器:本质势函数,(装饰其它函数)就是为其他函数添加附加功能。

    原则:1、不能修改被被装饰的函数的源代码

                  2、不能修改被装饰的函数的调用方式

    实现装饰器的知识储备:

    1、函数即“变量”

    2、高阶函数

    3、嵌套函数

    高阶函数 + 嵌套函数 = 装饰器

    下面举个列子:

    【高级版】

    import time     #申明库
    def timer(func):    #定义timer函数
        def deco(*args,**kwargs):     #定义deco函数,(嵌套函数)
            start_time = time.time()    #获取func函数开始的时间
            func(*args,**kwargs)      #执行func函数
            stop_time = time.time()     #获取func函数结束的时间
            print('the func run time is %s'%(stop_time-start_time))     #打印func函数执行的总时间
        return deco     #在timer函数中返回deco地址变量
    @timer  #装饰器  #test = timer(test)
    def test():
        time.sleep(3)
        print('in the test')
    test()

     

    【终极版】

    # -*- coding:utf-8 -*-
    #!/usr/bin/env python
    # Author:suchagal
    username = 'xuwei'
    password = 'suchagal'
    def auth(auth_type):
        def outer_wrapper(func):
            def wrapper(*args, **kwargs):
                if auth_type == 'local':
                     users = input('input username:').strip()
                     passwd = input('input passwd:').strip()
                     if users == username and passwd == password:
                        res = func(*args, **kwargs)
                        print('33[32;1mwelcome to home33[0m')
                        return res
                     else:
                        exit('33[31;1minvalid input33[0m')
                elif auth_type == 'ldap':
                    print('什么ldap,我不会。。。')
            return wrapper
        return outer_wrapper
    
    @auth(auth_type = 'local') #home = auth(home)
    def home(name):
        print('i am home',name)
        return 'xuwei'
    
    @auth(auth_type = 'ldap')
    def bbs():
        print('i am bbs')
    
    home('daweige')
    bbs()

     

    这个装饰器的目的是提供不同的认证方式,可以再本地认认证们也可以在远端认证LDAP认证。装饰器传进去的参数的不同,来进行认证。

    个人理解:装饰器本质就是将被装饰的函数“门牌号”传递给另一个函数的“门牌号”,然后通过修改该函数体来改变函数,最后再将“门牌号”传递回来。

    1.1.2 调用函数

    调用Python中的定义的函数(也就是不需要import就可以直接用的函数),可以在任何地方调用。

    还有调用一些函数时是需要import的,这个应该是对应组件中的函数,比如:import re就可以调用正则函数;import sys就可以调用系统对应的函数;import os就可以调用目录结构的相关函数;import time就可以调用系统时间的相关函数;import copy就可以实现深copy(见5.1.7)。

    调用自己写的函数,分为两种情况(目前我所知道的,知增录扩)

    1、在相同的Python文件目录下

    直接import Python的文件名,然后文件名.方法名();

    2、在不同的Python文件目录下

    先要添加上层目录地址,再from xxx import xxx;如下:

    import os
    import sys
    
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(BASE_DIR)
    from conf import settings
    from core import main

     

    1.1.3 生成器

    列表生成器:

    [i*2 for i in rangae(10)]

    >>>[0 2 4 6 8 10 12 14 16 18]

    原理:列表生成器在没有执行之前是“门牌号”储存在计算机内存中的,也就是说在计算机内存中不是“[0 2 4….]”。这样可以省内存!

    再举个例子:

    # -*- coding:utf-8 -*-
    #!/usr/bin/env python
    # Author:suchagal
    
    import time
    def consumer(name):
        print('%s 准备吃包子啦!' %name)
        while True:
            baozi = yield
            print("包子[%s]来了,被[%s]吃了!" %(baozi,name))
    
    def productor(prod_name):
        c = consumer('小明')
        c1 = consumer('小小明')
        c.__next__()       #执行一次consumer()函数
        c1.__next__()      #同上
        print("33[31;1m%s开始做包子了!33[0m" %prod_name)
        weidao = ['韭菜','大白菜','猪肉','牛肉','羊肉','空心菜','榨菜','小白菜','鸭肉','鸡肉']
        for i in weidao:
            time.sleep(1)
            print("做了两个包子")
            c.send(i)  #将weidao发送给baozi
            c1.send(i)     #同上
    
    productor("小明")

    上面的函数可以在单线线程下执行多线程的效果,这个就是nginx单线程会比其他多线程还要快几倍的原因!

    1.1.4 迭代器

    我们已经知道,可以直接作用于for循环的数类型有以下几种:

    一类是集合数据类型,如list、tuple、dict、set、str等;

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

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

    *可以使用isinstance()判断一个对象是否是iterable(迭代器)对象:

    而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,知道最后抛出stopiteration异常错误表示无法集训返回下一个值。

    可以被next()函数调用并不断返回下一个值的对象成为迭代器。

    生成器一定是迭代器,迭代器不一定是生成器。

    1.1.5 内置函数

    print(abs(-7))  #取绝对值
    print(all([1,2,3,4]))   #列表中的元素都为真返回true,有一个为假则返回false
    print(any([0,0,0])) #列表中的元素都为假返回false,至少有一个则返回true
    a = ascii([1,2,'xuwei','suchagal']) #将一个列表,字典,变成字符
    print(type(a),[a])
    b = eval('''[1,2,'xuwei','suchagal']''')    #取注释
    print(b[2])
    print(bin(34))  #十进制转二进制
    print(bool(1))  #判断真假,也可以判断列表
    print(bool([]))
    
    a = bytes('abcde',encoding='utf-8') #str不可以修改
    print(a.capitalize(),a)
    b = bytearray('abcde',encoding='utf-8') #可以修改str
    print(b[1])
    b[1] = 101
    print(b)
    
    def ssaf():pass
    print(callable(ssaf)) #可以调用返回true,不可调用返回false
    
    print(chr(98)) #返回数字在ASCII码中对应的str
    print(ord('b')) #返回ASCII中的str对应的数字
    
    compile()  #将一串字符串代码执行(忘记它吧,没什么卵用)
    exec() #可以将一个被注释的程序执行
    eval() #去掉注释,并执行,被注释的部分非程序
    
    dir()  #查看该类,字典有什么方法
    dict(a=b,c=3)  #生成一个字典
    divmod(5,3)    #返回一个5/3=(1,2)
    
    res = filter(lambda n:n*n,range(10))
    for i in res:
        print(i)
    
    sas = map(lambda n:n*2,range(10))   #将后面range的值传个lambda处理,处理完了传给map
    for ii in sas:
        print(ii)
    print(sas)
    
    import functools
    res = functools.reduce(lambda x,y:x+y,range(10))
    print(res)
    
    a = frozenset([12,3,23,34,3,45,22,22])  #让集合没有怎删改查的选项
    
    print(globals())    #显示出当前文件中的全局变量(字典类型)
    print(locals()) #打印局部变量
    print(hex(3234))    #将一个数字转成16进制

     The unexamined life is not worth living.--Socrates

    浑浑噩噩的生活不值得过.

  • 相关阅读:
    leetcode 279. Perfect Squares
    leetcode 546. Remove Boxes
    leetcode 312. Burst Balloons
    leetcode 160. Intersection of Two Linked Lists
    leetcode 55. Jump Game
    剑指offer 滑动窗口的最大值
    剑指offer 剪绳子
    剑指offer 字符流中第一个不重复的字符
    leetcode 673. Number of Longest Increasing Subsequence
    leetcode 75. Sort Colors (荷兰三色旗问题)
  • 原文地址:https://www.cnblogs.com/suchagal/p/8477800.html
Copyright © 2020-2023  润新知