zoukankan      html  css  js  c++  java
  • python 第五天

    双层装饰器
    #一个装饰器用另一个装饰器的功能
    #一个函数用两个装饰器
    #第三

    #双层装饰器记法:
        #---解释时从下往上解释
        #---执行时从上到下执行
       
    解释顺序:
    1.将index函数传给check_admin,生成新的函数(即check_admin的inner),老index函数为check_admin的func
    2.将check_admin函数传给check_login,生成新的函数(即check_login的inner),老的check_admin的inner变成了func
       
    执行顺序:
    1.执行check_login函数,判断成功后执行func即check_admin的inner函数
    2.再执行check_admin的inner函数,判断成功后执行执行func即原始index函数

    @check_login                                     #第二次装饰,相当于在第一次装饰完成后用新生成的”新的index函数“又被创建了一个”新的index函数“
    @check_admin                                     #第一次装饰,相当于创建了一个 "新的index函数",是check_admin的inner函数体
    def index():
        print('index')   
       
       
       
       
       
    #双层装饰器程序   
    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    # Author:Minghu Wang

    #判断登录
    USER_INFO = {}
    #USER_INFO['is_login']
    #USER_INFO.get('is_login',None)

    def check_login(func):
        def inner(*args, **kwargs):
            if USER_INFO.get('is_login',None):       #如果is_login为真时,.get是判断is_login的values值不存在,返回None,即定位默认值
            #.get 如果键值不存在,可定义第二个参数,返回None
                ret = func(*args, **kwargs)              #check_admin生成的”新的index“函数
                return ret
            else:
                print('请登录')                       #没登录返回信息
        return inner


    #只判断管理,不判断登录
    def check_admin(func):
        def inner(*args, **kwargs):

            if USER_INFO.get('user_type',None) == 2:
                ret = func(*args, **kwargs)          #原index函数
                return ret
            else:
                print('无权限查看')                  #登录后,无权查看选项返回信息

        return inner

    #一个函数用两个装饰器,从下到上装饰   
    @check_login                                     #第二次装饰,相当于在第一次装饰完成后用新生成的”新的index函数“又被创建了一个”新的index函数“
    @check_admin                                     #第一次装饰,相当于创建了一个 "新的index函数",是check_admin的inner函数体
    def index():
        print('index')

    @check_login
    def home():
        print('home')

    def login():
        user = input('请输入用户名:')
        if user == 'admin':
            USER_INFO['is_login'] = True
            USER_INFO['user_type'] = 2
        else:
            USER_INFO['is_login'] = True
            USER_INFO['user_type'] = 1

    def main():
        while True:
            inp = input('1,登录; 2,查看信息; 3,超级管理员管理 >>>')
            if inp == '1':
                login()
            elif inp == '2':
                home()
            elif inp == '3':
                index()
    main()

    字符串格式化
        两种方法:format 和 %

        % 常用字符串格式化
            tpl = "i am %s" % "alex"
            tpl = "i am %s age %d" % ("alex", 18)
            tpl = "i am %(name)s age %(age)d" % {"name": "alex", "age": 18}         #定义变量,以字典方式格式化
            tpl = "percent %.2f" % 99.97623                                         #取小数点后两位
            tpl = "i am %(pp).2f" % {"pp": 123.425556, }                            #把pp的key值传入,再取小数点后两位
            tpl = "i am %.2f %%" % 123.425556                                       #取小数点后两位,取百分号,%%防转义

        format字符常用方法
            tpl = "i am {}, age {}, {}".format("seven", 18, 'alex')                                  #{}为空占位符,随意传,按顺序参数
            tpl = "i am {}, age {}, {}".format(*["seven", 18, 'alex'])                               #给列表加*是分别按顺序给占位符传值,不然会报错
            tpl = "i am {0}, age {1}, really {0}".format("seven", 18)                                #{}占位符中指定索引号是为了传固定的值,不按顺序传,自由度高
            tpl = "i am {0}, age {1}, really {0}".format(*["seven", 18])                             #把列表传给{}占位符索引,用*分别传值
            tpl = "i am {name}, age {age}, really {name}".format(name="seven", age=18)               #{name} 占位符变量名,按变量名传值
            tpl = "i am {name}, age {age}, really {name}".format(**{"name": "seven", "age": 18})     #{name} 占位符变量名,**以字典分别将key的value值传值
            tpl = "i am {0[0]}, age {0[1]}, really {0[2]}".format([1, 2, 3], [11, 22, 33])           #{0[0]}占位符作用是以列表的索引的元素位值传值
            tpl = "i am {:s}, age {:d}, money {:f}".format("seven", 18, 88888.1)                     #{:s}等以固定类型传值,{s:}字符串,{:d}数字,{:f}浮点型
            tpl = "i am {:s}, age {:d}".format(*["seven", 18])                                       # * 星的作用是把列表值分别传给固定的类型
            tpl = "i am {name:s}, age {age:d}".format(name="seven", age=18)                          #{name:s}等是以变量和固定类型限制传的值必须是固定类型
            tpl = "i am {name:s}, age {age:d}".format(**{"name": "seven", "age": 18})                # ** 双星的作用是把字典的value值分别传入
            tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)  #按{:b}二进制,{:o}八进制,{:d}十进制,{:x}十六进制,{:X}大写十六进制,{:%}百分比  传值
            tpl = "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15)                         #按索引传值,用各种进制和类型转换
            tpl = "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%}".format(num=15)         #指定变量num,按变量传值,用各种进制和类型转换

    #左对齐减号  -10  包含字符长度
    s = "asdf%(name)  -10saaa %(age)-10d   %(p).2f" %{'name':'alex','age': -123, "p": 1.236567}
    print(s)

    #进制转换 %s  %c %x %g
    s  = "asdifuyaksdf %c ---- %o  ===== %x ===== %g" %(65, 15, 15, 100)
    print(s)
    s1 = "alex %"
    print(s1)

    #当格式化时,字符串中出现占位符 %s.. 需要用 %% 输出 %
    s2 = "alex %s %%" %('SB')
    print(s2)

    #根据索引号传值
    s1 = "asdfasdf{0}a123{0}123{1}".format(123, "alex")
    print(s1)


    #固定类型格式化
    s1 = "----{name:s}____{age:d}===={name:s}".format(name='alex', age=123)
    print(s1)

    #居中格式化
    s2 = "----{:*^20s}====={:+d}===== {:x}".format('alex', 123, 15)
    print(s2)

    #取小数点后两位并带百分比
    s3 = "asdfasdfasd {:.2%}".format(0.234567)
    print(s3)

    生成器  (yield)
        出现yield 就是生成器
        yield 控制顺序,保存上次执行的位置
        生成器,本质就是yield控制位器,按顺序一个一个执行

    程序1
    def func():
        print(1111)
        yield 1
        print(222)
        yield 2
        print(333)
        yield 3

    ret = func()
    r1 = ret.__next__() #进入函数找到yield,获取yield后的数据,__next__ 一个一个拿yielld函数位的值
    print(r1)
    r2 = ret.__next__() #进入函数找到yield,获取yield后的数据
    print(r2)
    r3 = ret.__next__() #进入函数找到yield,获取yield后的数据
    print(r3)
    # r4 = ret.__next__() #进入函数找到yield,获取yield后的数据
    # print(r4)


    #自写range功能1
    def myrange(arg):
        start = 0
        while True:
            if start > arg:
                return
            yield  start

            start += 1
    ret = myrange(3)
    r = ret.__next__()
    print(r)
    r = ret.__next__()
    print(r)
    r = ret.__next__()
    print(r)
    r = ret.__next__()
    print(r)


    #自写range功能2
    def myrange(arg):
        start = 0
        while True:
            if start > arg:
                return
            yield  start

            start += 1
    ret = myrange(3)            #循环遍历四次(包括0)
    for item in ret:
        print(item)
       
       
       
       
       

    函数嵌套调用
    def d():
        return '123'

    def c():
        r = d()              #调用d函数
        return r

    def b():
        r = c()                 #调用c函数
        return r

    def a():   
        r = b()                 #调用b函数
        print(r)

    a()                     #执行a函数,应该一层层找,打印123

    递归函数
    def func(n):
        n += 1
        print(n)
        if  n > 4:
            return 'end'
        return func(n)     #这个return为了返回函数结果(end)

    r = func(1)
    print(r)


    模块:
        内置模块
        自定义模块
        第三方模块

        为什么要有模块?
            将代码归类

    导入模块的依据
        import sys
        sys.path
       

    模块
    py:模块
    其他:类库
            先导入
            后写入

    sys.argv传参模块:

    #a.py程序
    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    # Author:Minghu Wang
    import sys
    print(sys.argv)

    python a.py  jkdsjf jfkdsjf  jksfdjf


    #函数调用(导入)

    #目录结构
    day5/
    ├── lib
    │?? ├── commons.py
    │?? └── __pycache__
    │??     └── commons.cpython-35.pyc
    ├── __pycache__
    │?? └── s4.cpython-35.pyc
    ├── s3.py                               #执行函数,调用s4.py、lib/commons.py
    ├── s4.py
    └── s4.pyc

    lib  目录下的
    commons.py
        #!/usr/bin/env python
        #-*- coding:utf-8 -*-
        # Author:Minghu Wang
        def f1():
            print("F1")

    s4.py
        #!/usr/bin/env python
        #-*- coding:utf-8 -*-
        # Author:Minghu Wang
        def login():
            print("login")
           
        def logout():
            print('logout')

    执行函数
    s3.py
        #!/usr/bin/env python
        #-*- coding:utf-8 -*-
        # Author:Minghu Wang
        import s4
        import lib.commons

        s4.login()
        lib.commons.f1()

    结果
        login
        F1


    跨目录导模块
        sys.path  #导入模块先到sys.path的目录找
        从上到下找,找不到就报错

    在opt目创建脚本
    vi /opt/outer.py
    def aa():
        print('wmh')


    在任意目录创建脚本调用
    #导入我的模块
    vi  /root/a.py
    import sys
    sys.path.append("/opt")
    import outer
    outer.aa()


    执行a.py
    python a.py

    返回结果
    wmh

    #模块名称非常重要,不要和内置重名
    #创建自己的模块不要和内置模块一样,不然只执行自己的,不执行内置的
    import sys
    print(sys.path)


    #执行函数
    s3.py
    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    # Author:Minghu Wang
    import lib.commons
    from  s4 import login   #从s4.py模块 导入login函数
    login()                    #直接执行

    s4.login()
    lib.commons.f1()

    调用模块方法
        from s4 import *      #导入s4.py模块所有函数
        from lib import commons  #导入同级lib目录的commons.py模块
        commons.f1()  


    #模块别名
    from lib  import commons1 as commons1
    from lib  import commons as commons2

    #导入模块
    单模块
        使用  import
    嵌套文件夹下
        使用    from lib  import commons          #单独导入
                from lib  import commons as f1    #别名


    #安装requests
    #加环境变量
    C:UsersAdministratorAppDataLocalProgramsPythonPython35Scripts  
    python3 -m pip install --upgrade pip
    python3 -m pip install requests

    import requests

    序列化模块
    json
        json.dumps  #将pyhton 基本数据类型转成字符串       (序列化)
        json.loads  #将python字符串形式转化成基本数据类型    (反序列化读)
    使用方法
        import json          
        import pickle


    json使用dumps
        a.py
            import json
            dic = {'k1':'v1'}
            print(dic,type(dic))
            result = json.dumps(dic)    # dumps将pyhton 基本数据类型转成字符串形式
            print(result,type(result)) 

    返回结果
    {'k1': 'v1'} <class 'dict'>            #原为字典
    {"k1": "v1"} <class 'str'>               #dumps转后成为字符串类型


    json使用loads
        b.py
            import json
            s1= '{"k1":123}'
           
            dic  = json.loads(s1)         # loads将python字符串形式转化成基本数据类型
            print(dic,type(dic))

    返回结果
    {'k1': 123} <class 'dict'>

    使用requests抓取页面字符,用json的loads转成字典打印
    import json
    import requests
    response = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=北京')
    response.encoding = 'utf-8'
    print(response.text)
    dic = json.loads(response.text)  #response.text是request的用法,获取http内容
    print(dic,type(dic))


    注意点
    import json
    r = json.dumps([11,22,33])
    li = '["alex","eric"]'    #必须以单引在外,双引在内,不然报错
    ret = json.loads(li)         #通过loads反序列化时,一定要用""双引号
    print(ret,type(ret))


    #dump 将列表序列化写到文件
    import json
    li = [11,22,33]
    json.dump(li,open('db','w'))       #将列表序列化写到文件


    #load 将文件反序列化读输出
    import json
    li = json.load(open('db','r'))     #将文件反序列化读输出
    print(type(li),li)                 

    json / pickle  区别
        json 更加适合跨语言,字符串基本数据类型
        pickle 所有类型的序列化,仅适用pyhton,可以用于存储加密的程序
        常用为对文件操作


    pickle 序列化使用

    #程序1
    import pickle
    li = [11,22,33]
    r = pickle.dumps(li)    #序列化成python专用类型,你不知道的类型,python专用
    print(r)

    result = pickle.loads(r)   #将python 类型用loads载入反序列化输出
    print(result)


    #程序2
    li = [11,22,33]
    pickle.dump(li,open('db','wb'))     #用dump方法以python特定写入到文件

    result = pickle.load(open('db','rb'))    #使用load反序列化载入输出
    print(result,type(result))

    time 和 datetime 模块使用
    import time
    import datetime
    print(time.time())  #时间戳
    print(time.ctime())  #当前时间
    print(time.ctime(time.time()-86400))  #昨天
    print(time.gmtime())


    time_obj = time.gmtime()
    print(time_obj)
    print(time_obj.tm_year,time_obj.tm_mon)    #取年、月
    print(time.localtime())    #本地时间
    print(time.mktime(time_obj))   #转成时间戳

    #睡眠4秒
    time.sleep(4)       
    print("------")


    time.strftime("%Y-%m-%d %H:%M:%S",time.time())
    print("-------")
    tm = time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime())
    print(tm)
    tm = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
    print(tm)
    tm = time.strptime("2016-05-6","%Y-%m-%d")
    print(tm)
    tm = time.strptime("2016-05-6 15:06","%Y-%m-%d %H:%M")
    print(tm)
    tm = time.strptime("2016-05-6 15:06","%Y-%m-%d %H:%M")  #字符串转成时间戳
    print(time.mktime((tm)))
    print(datetime.date.today())
    print(datetime.date.fromtimestamp(time.time))


    #  time和datetime  使用

    #_*_coding:utf-8_*_
    import time                #取时间戳
    import datetime               #取日期

    print(time.clock()) #返回处理器时间,3.3开始已废弃
    print(time.process_time()) #返回处理器时间,3.3开始已废弃
    print(time.time()) #返回当前系统时间戳
    print(time.ctime()) #输出Tue Jan 26 18:23:48 2016 ,当前系统时间
    print(time.ctime(time.time()-86640)) #将时间戳转为字符串格式
    print(time.gmtime(time.time()-86640)) #将时间戳转换成struct_time格式
    print(time.localtime(time.time()-86640)) #将时间戳转换成struct_time格式,但返回 的本地时间
    print(time.mktime(time.localtime())) #与time.localtime()功能相反,将struct_time格式转回成时间戳格式
    #time.sleep(4) #sleep

    #常用取时间日期
    print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()) ) #将struct_time格式转成指定的字符串格式
    print(time.strptime("2016-01-28","%Y-%m-%d") ) #将字符串格式转换成struct_time格式

    #datetime module
    print(datetime.date.today()) #输出格式 2016-01-26 ,取今天
    print(datetime.date.fromtimestamp(time.time()-864400) ) #2016-01-16 将时间戳转成日期格式


    #常用2
    current_time = datetime.datetime.now() #
    print(current_time) #输出2016-01-26 19:04:30.335935
    print(current_time.timetuple()) #返回struct_time格式

    #datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]])
    print(current_time.replace(2014,9,12)) #输出2014-09-12 19:06:24.074900,返回当前时间,但指定的值将被替换

    str_to_date = datetime.datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M") #将字符串转换成日期格式
    new_date = datetime.datetime.now() + datetime.timedelta(days=10) #比现在加10天
    new_date = datetime.datetime.now() + datetime.timedelta(days=-10) #比现在减10天
    new_date = datetime.datetime.now() + datetime.timedelta(hours=-10) #比现在减10小时
    new_date = datetime.datetime.now() + datetime.timedelta(seconds=120) #比现在+120s
    print(new_date)

    时间博客
    http://www.cnblogs.com/alex3714/articles/5161349.html


    时间比较判断
    import time
    import datetime

    #时间比较判断
    current_time = datetime.datetime.now()
    time_obj = current_time.replace(2015,5)               
    print(current_time==time_obj)

       
       
       
       
       
    logging模块
        debug(), info(), warning(), error() and critical() 5个级别   
       

    最简单用法   
    import logging
    logging.warning("user [alex] attempted wrong password more than 3 times")
    logging.critical("server is down")
       
           
    #输出
    WARNING:root:user [alex] attempted wrong password more than 3 times
    CRITICAL:root:server is down
       
       
       
    ----Level------------------级别----------------------------------
        DEBUG             详细信息,综合诊断                 级别最低
        INFO            工作状态信息
        WARNING            异常警报,突发事件
        ERROR            严重错误,功能失效
        CRITICAL        严重错误,突然中断,不能继续运行
       
       
    日志写到文件里   
    #level=loggin.INFO 把日志纪录级别设置为INFO,INFO或比INFO级别更高写入文件
    #所以 debug信息不写入,因为级别低于info,如果想写,改level=logging.DEBUG即可
    import logging

    logging.basicConfig(filename='example.log',level=logging.INFO)  
    logging.debug('This message should go to the log file')
    logging.info('So should this')
    logging.warning('And this, too')
           

           
           
           
    记录时间日志
    import logging
    logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%Y/%m/%d %I:%M:%S %p')
    logging.warning('is when this event was logged.')
           

    终端和文件同时写需要学习的组件       
        logging库提供了多个组件:Logger、Handler、Filter、Formatter。
            Logger       对象提供应用程序可直接使用的接口,
            Handler      发送日志到适当的目的地,
            Filter          提供了过滤日志信息的方法,
            Formatter   指定日志显示格式。
           


           
           
    打印到终端同时写入到文件程序       
    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    # Author:Minghu Wang


    import logging
    #创建logger
    logger = logging.getLogger('TEST-LOG')           #创建一个logger
    logger.setLevel(logging.DEBUG)                     #配置级别
    #定义输出到终端
    ch = logging.StreamHandler()                       #创建handler,用于输出到终端
    ch.setLevel(logging.DEBUG)                         #配置输出终端日志级别
    #定义输出到文件
    fh = logging.FileHandler("access.log")           #创建一个handler,用于写入日志文件
    fh.setLevel(logging.WARNING)                       #配置写入文件日志级别
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')  #定义handler的输出格式formatter

    #定义日志输出格式
    ch.setFormatter(formatter)                         #以formatter定义的格式输出到终端
    fh.setFormatter(formatter)                         #以formatter定义的格式写入到文件
    #加载到handler
    logger.addHandler(ch)                             #将定义的 ch 日志输出功能添加到handler
    logger.addHandler(fh)                             #将定义的 fh 日志输出功能添加到handler

    #给日志级别定义内容,并应用
    logger.debug('debug message')                  #给日志级别定义内容,并应用
    logger.info('info message')
    logger.warn('warn message')
    logger.error('error message')
    logger.critical('critical message')
           
           
           
           
           
    结果
    2016-06-08 15:54:30,973 - TEST-LOG - DEBUG - debug message
    2016-06-08 15:54:30,973 - TEST-LOG - INFO - info message
    2016-06-08 15:54:30,973 - TEST-LOG - WARNING - warn message
    2016-06-08 15:54:30,974 - TEST-LOG - ERROR - error message
    2016-06-08 15:54:30,974 - TEST-LOG - CRITICAL - critical message       

  • 相关阅读:
    Rabbitmq
    Python() with语法糖
    Python()-类的专有方法之双下划线方法
    git配置踩过的坑
    https 协议 和 ssh 协议在使用上的差别
    Definite dimensionality
    java中定义和声明的区别
    数据库中表的数据逻辑删除的方案
    StringBuffer、StringBuilder和String的区别?
    常量池中的String与堆中的String
  • 原文地址:https://www.cnblogs.com/wangminghu/p/5570481.html
Copyright © 2011-2022 走看看