zoukankan      html  css  js  c++  java
  • 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

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

  • 相关阅读:
    The .NET weak event pattern in C#
    Setting an Event to Null
    Android: INSTALL_FAILED_UPDATE_INCOMPATIBLE错误解决措施
    快速打开 Mac OS X 隐藏的用户资源库文件夹
    Complete uninstall on Mac, HELP!
    为什么MacBook装Windows这么火?
    mac 刻录ISO系统盘
    MySQL子查询慢现象的解决
    程序人生的四个象限和两条主线
    Xamarin.Android,Xamarin.iOS, Linking
  • 原文地址:https://www.cnblogs.com/suchagal/p/8477800.html
Copyright © 2011-2022 走看看