• day08面向对象、jsonpath操作、写日志


    一、上周作业

    # 1.写一个程序,传入一个群号,把这个群里所有人的头像下载到本地,头像的名字
    # 如果这个人有群备注,那么图片的名称就是名字.jpg,如果没有名称就取昵称
    # 因为需要登录,所以需要cookie
    # https://q4.qlogo.cn/g?b=qq&nk=857566034&s=140

    1.分析

    import requests
    import os
    
    #判断存在否,不存在创建文件夹
    if not os.path.exists('qq_pics'):
        os.mkdir('qq_pics')
    os.chdir('qq_pics')
    
    max_count = 200
    gc = '1078641913'
    group_member_url = 'https://qun.qq.com/cgi-bin/qun_mgr/search_group_members'
    size = 20#定义步长
    brn = 2027956891#可变的
    cookie = ''
    #群里面最多200人
    #0,20;21:41;42:62;....
    count = 0
    for j in range(0,max_count+1,20):
    
        headers = {
            'user-agent': 'Mozilla/5.0',
            'cookie': 'uin=o0544487209; skey=@EaiQXzjCW; RK=5NQIdFmjOh; ptcz=bfdea3df51354dc33cd2968594175f2ac8e8c56e2fd70a6067b2e92f1e78cd86; p_uin=o0544487209; pt4_token=c9ZNSP*7XNRwG5UgwGdvMbkYsXywb21nwYaqwaD39Ds_; p_skey=S-ceAUF1J0euCGX5Dqne6uBfHAGJp-RJqG5OSxRoA98_; traceid=9da1ab4551'
    }
    
        data = { 'gc': gc,'st': j,'end': j+size+count,'sort': 0,'bkn': 2027956891}
    
        r = requests.post(group_member_url,data,headers=headers)
        members = r.json()
        count += 1
        if 'mems' in members:
            pic_url ='https://q4.qlogo.cn/g?b=qq&nk=%s&s=140'
            #all_count = members.get('count')
            mems = members.get("mems")
            for m in mems:
                qq = m.get("uin")
                #如果card的值取到了,就取card,没有取到取nick,非空即真
                name = m.get('card') if m.get('card') else m.get('nick')
                r = requests.get(pic_url %qq)
                with open(name+'.jpg','wb') as fw:
                    fw.write(r.content)
                print('下载完成%s'%name)
        else:
            print('没有获取到群成员信息')
            break
    View Code

    2.登录并支付

    # 2.写登录接口,登录成功之后返回seesionid:xxx
    # 当前时间戳time.time()+username,做md5 生成sessionid,session过期时间,自己定义
    # seesion会放到redis里面,
    # redis里面存进入sessionid,fd:userid,time过期时间
    # 2.2支付接口
    # 建表table、存userid和money
    # 1,20000
    # /pay?sessionid=xxxx&money=90
    #校验sessionid是否失效,取不到不是错的就是过期了,如果支付金额>余额数据库的就失败,<就成功扣钱
    import time
    import flask
    import tools,json
    import uuid
    server = flask.Flask(__name__)
    
    #登录
    @server.route('/login',methods=['post','get'])
    def login():
        username = flask.request.values.get('username','')
        password = flask.request.values.get('password','')
    
        if username.strip() and password.strip():
            #给密码加密
            p = tools.my_md5(password)
            #从mysql获取是否存在
            query_sql = 'select * from app_myuser where username= "%s" and passwd="%s";' % (username, p)
            user_result = tools.execute_sql(query_sql)
            if user_result:
                #生成sessionid,session是使用用户名+时间戳+uuid生成的
                session_str = '%s%s%s'%(username,time.time(),uuid.uuid4())
                #加密
                session_id = tools.my_md5(session_str)
                #获取ID,name,存入redis中
                user_id = user_result.get('id')
                #存入key.value,超时时间,注意写入方式
                tools.redis_str(session_id, '{"user_id":%s,"username":"%s"}' % (user_id, username), 600)
                return json.dumps({'code': '0', 'msg': '登录成功','sessionid':session_id},ensure_ascii=False)
            else:
                return json.dumps({'code': '-1', 'msg': '输入的用户名/密码错误'})
        else:
            return json.dumps({'code': '-1', 'msg': '不能为空'})
    
    
    
    # print(uuid.uuid4())
    #支付
    @server.route('/pay',methods=['post','get'])
    def pay():
        tools.logger.debug('进入支付接口')
        sessionid = flask.request.values.get('sessionid','')
        money = float(flask.request.values.get('money'))
        tools.logger.debug('请求参数:{}',flask.request.values)
    
        session = tools.check_session(sessionid)
        if session:
            user = json.loads(session)
            user_id = user.get('user_id')
            sql = 'select balance from app_myuser where id = %s;'%user_id
            tools.logger.debug('sql语句:{}',sql)
            balance = tools.execute_sql(sql).get('balance')
            if balance>=money:
                update_money = 'update app_myuser set balance = balance - %s where id = %s;' %(money,user_id)
                tools.execute_sql(update_money)
                return json.dumps({'code': 0, 'msg': '支付成功'},ensure_ascii=False)
            else:
                return json.dumps({'code': -1, 'msg': '余额不足'},ensure_ascii=False)
        else:
            return json.dumps({'code': 899, 'msg': '请登录!'},ensure_ascii=False)
    
    
    if __name__ == '__main__':
        server.run(host='127.0.0.1',port=8999,debug=True)
    
    #在网站上输入这个地址查询
    #http://127.0.0.1:8999/login?username=niuhanyang2&password=1
    #http://127.0.0.1:8999/pay?money=1&sessionid=bcaee6b6b1a2746f27b1dbc5488003f5
    View Code

     二、tools文件新增

    import traceback,hashlib
    
    import pymysql
    import redis
    import xlwt
    from loguru import logger
    import sys
    
    logger.remove()  # 清除它的默认设置设置
    fmt = '[{time}][{level}][{file.path}:line:{line}:function_name:{function}] ||msg={message}'
    # level file function module time message
    logger.add(sys.stdout, level='INFO', format=fmt)  # 咱们本地运行的时候,在控制台打印
    # logger.add('wxl.log',level='DEBUG',format=fmt,encoding='utf-8',enqueue=True,rotation='1 s',retention='10 seconds')#写在日志文件里面
    logger.add('wxl.log', level='DEBUG', format=fmt, encoding='utf-8', enqueue=True, rotation='1 day',
               retention='10 days')  # 写在日志文件里面
    
    MYSQL_INFO = {
        'host':'118.24.3.40',
        'user':'jxz',
        'password':'123456',
        'db':'jxz',
        'charset':'utf8',
        'autocommit':True
    
    }
    
    REDIS_INFO = {
        'host':'118.24.3.40',
        'password':'HK139bc&*',
        'port':'6379',
        'db':'4',
        'decode_responses':True #自动返回字符串
    }
    
    def execute_sql(sql,more=False):
        #连接数据库
        conn = pymysql.connect(**MYSQL_INFO) #xx=xxx,xx=xx
        cur = conn.cursor(pymysql.cursors.DictCursor)  # 游标
        try:
            cur.execute(sql)#没有问题,执行这句
        except:
            logger.error('sql错误,{}',traceback.format_exc())
            # print('sql不正确')#不正确走这句
            # traceback.print_exc()
        # else:
        #     return cur.fetchall() #None [{}]
        else:#执行完try执行else中的
            if more:
                return cur.fetchall() #None [{}]
            return cur.fetchone() #{'xx':'xx'}
        finally:
            conn.close()
            cur.close()
    
    class Tool:
    
        @staticmethod
        def write_excel(name,data):
            book = xlwt.Workbook()
            sheet = book.add_sheet('sheet1')
            # 获取表头,写表头
            for index, key in enumerate(data[0]):#写表头
                sheet.write(0, index, key)
            for row, item in enumerate(data, 1): #写数据
                for col, value in enumerate(item.values()):
                    sheet.write(row, col, value)
    
            book.save(name + '.xls')
            print('导出完成')
    
        # @staticmethod
        # def my_md5(s):
        #     s = str(s)
        #     s = s.encode()
        #     m = hashlib.md5(s)  # bytes,不可逆
        #     result = m.hexdigest()
        #     return result
    
    def my_md5(s):
        s = str(s)
        s = s.encode()
        m = hashlib.md5(s)  # bytes,不可逆
        result = m.hexdigest()
        return result
    
    def redis_str(key,value=False,expire_time=None):
        r = redis.Redis(**REDIS_INFO)
        if value:
            r.set(key,value,expire_time)
        else:
            return r.get(key)
    
    def redis_hash():
        pass
    
    #校验sessionid
    def check_session(session_id):
        result = redis_str(session_id)
        if result:
            return result
        return False
    View Code

    三、写日志

    import logging   #python自带的工具
    import loguru #第三方的写日志
    import sys,time
    from loguru import logger
    #debug #调试信息,最低的级别
    #info #正常的提示信息
    #waring #警告信息
    #error #出错了 ,走不动  #50-100
    #写日志是io操作,会影响内存,一般正式环境设置日志级别都是
    #exception #程序出异常了  sql执行出错了
    def fd():
        logger.remove() #默认的设置清楚掉,debug
        #设置日志级别
        #stdout程序的标准输出,操作系统print才能在屏幕中写东西
        # level file function module time message
        fmt = '[{time}][{level}][{file.path}:line:{line}:function_name:{function}] ||msg={message}'
        logger.add(sys.stdout,level='INFO',format=fmt)#本地运行,在控制台打印
        #写到日志文件中
        #enqueue=True异步写日志:先把日志放到消息队列里面,在启动一个线程,慢慢写进去,可以提高性能
        #rotation默认时间:
        #rotation可以设置大小,超过多大就产生一个新文件1 kb,500 m,1 g
        #rotation可以多长时间,1 day,1 hour
        #rotation几点创建新文件,00:00,1:00
        #retention删除日志,当前的日志不会受影响
        logger.add('fd.log',level='DEBUG',format = fmt,encoding='utf-8',enqueue=True,rotation='1 day',retention='10 days')#部署到服务器的时候写在日志文件中
        #超过20kb就会创建一个新的文件,最新的都是在不带日期中的
        # logger.add('demo1.log',rotation='500 MB') #文件过大就会重新生成一个文件
        # logger.add('demo1.log', rotation='01:00') #每天1点创建新文件
        # logger.add('demo1.log', rotation='2 week')# 2个星期文件时间过长就会创建新文件
        # logger.add('demo1.log', retention='7 days')#一礼拜后会清空除了当前日志之前的日志,
        for i in range(20):
            time.sleep(1)
            logger.debug('程序开始运行了')
            logger.debug('开始连接mysql')
            logger.info('mysql配置xxxx')
            logger.warning('警告,磁盘空间即将不足')
            logger.error('程序出错了')
            # logger.exception('出错了')#使用exception会出现NoneType:None
    
    fd()
    #同步==高并发,所以使用异步写日志
    def write_log(msg):
        with open('a.log','a',encodong='utf-8') as fw:
            fw.write(msg)
    View Code

    四、jsonpath操作

    s= {"ec":0,"errcode":0,"em":"","cache":0,"adm_num":3,"levelname":None,"mems":[{"uin":511402865,"role":0,"g":0,"join_time":1589360442,"last_speak_time":1600570983,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"u671du82b1u5915u62fe","qage":14,"rm":0},{"uin":475566024,"role":1,"g":0,"join_time":1589360443,"last_speak_time":1596195430,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"CC","qage":15,"rm":1},{"uin":616745045,"role":1,"g":0,"join_time":1589360443,"last_speak_time":1589360443,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"u5927u5e08u5144","qage":14,"rm":1},{"uin":1473732204,"role":1,"g":0,"join_time":1589360443,"last_speak_time":1596699591,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"u5b89u5927u53d4","qage":10,"rm":1},{"uin":1930890111,"role":2,"g":-1,"join_time":1589360638,"last_speak_time":1589363741,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"56","qage":9,"rm":1},{"uin":549313033,"role":2,"g":0,"join_time":1590131830,"last_speak_time":1597542612,"lv":{"point":0,"level":1},"card":"u767du5b87u9e4f","tags":"-1","flag":0,"nick":"u79e6u6b87","qage":12,"rm":1},{"uin":121654011,"role":2,"g":1,"join_time":1591326665,"last_speak_time":1597549705,"lv":{"point":0,"level":1},"card":"u8e6du8bfe-u66f9u4e3au7f8e","tags":"-1","flag":0,"nick":"u265dAimeeu00b7Toou2740","qage":14,"rm":1},{"uin":411732604,"role":2,"g":1,"join_time":1591326665,"last_speak_time":1591584091,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"u4e09u53f6u8349u7684u624bu6307","qage":14,"rm":1},{"uin":690763103,"role":2,"g":1,"join_time":1591326665,"last_speak_time":1599960754,"lv":{"point":0,"level":1},"card":"u674eu9ad8u82f1","tags":"-1","flag":0,"nick":"u4e24u6b21u65b9u7684u65cbu5f8b","qage":12,"rm":1},{"uin":1522503760,"role":2,"g":0,"join_time":1591326665,"last_speak_time":1598146137,"lv":{"point":0,"level":1},"card":"u79b9u6881","tags":"-1","flag":0,"nick":"u79b9u6881","qage":9,"rm":1},{"uin":635763064,"role":2,"g":1,"join_time":1592997221,"last_speak_time":1600572109,"lv":{"point":0,"level":1},"card":"u970du7d2bu9633","tags":"-1","flag":0,"nick":"u6f02u6d41u6d77u5cb8","qage":13,"rm":1},{"uin":857566034,"role":2,"g":1,"join_time":1593329449,"last_speak_time":1600565621,"lv":{"point":0,"level":1},"card":"u4ee3u723d","tags":"-1","flag":0,"nick":"u767du7fbdu5f52u697c","qage":12,"rm":1},{"uin":347158400,"role":2,"g":0,"join_time":1593345739,"last_speak_time":1599385077,"lv":{"point":0,"level":1},"card":"u6731u6210","tags":"-1","flag":0,"nick":"u9ea6u514b.vod","qage":16,"rm":1},{"uin":704096641,"role":2,"g":1,"join_time":1594023174,"last_speak_time":1600572110,"lv":{"point":0,"level":1},"card":"u803fu5a1f","tags":"-1","flag":0,"nick":"704096641","qage":13,"rm":1},{"uin":978502577,"role":2,"g":1,"join_time":1594883618,"last_speak_time":1599992058,"lv":{"point":0,"level":1},"card":"u5f20u4e39u96ea","tags":"-1","flag":0,"nick":"u3000u3000Amouru256eu66aeu5ff5","qage":9,"rm":1},{"uin":799614279,"role":2,"g":0,"join_time":1594884719,"last_speak_time":1600565607,"lv":{"point":0,"level":1},"card":"u9c81u6d25u5065","tags":"-1","flag":0,"nick":"u4e28u5bd2u5c10u6708u309e","qage":13,"rm":1},{"uin":695254152,"role":2,"g":0,"join_time":1594886366,"last_speak_time":1600572106,"lv":{"point":0,"level":1},"card":"u738bu7965u9f99","tags":"-1","flag":0,"nick":"u8ffdu68a6u8d64u5b50u5fc3","qage":13,"rm":1},{"uin":251202767,"role":2,"g":1,"join_time":1594943472,"last_speak_time":1600572310,"lv":{"point":0,"level":1},"card":"u9ad8u96ef","tags":"-1","flag":0,"nick":"u7d2bu8272u7cbeu7075","qage":16,"rm":1},{"uin":120617143,"role":2,"g":1,"join_time":1595481073,"last_speak_time":1596951515,"lv":{"point":0,"level":1},"card":"u7b71","tags":"-1","flag":0,"nick":"u6668u98ceu5915u96e8","qage":18,"rm":1},{"uin":357084975,"role":2,"g":1,"join_time":1595817181,"last_speak_time":1600572106,"lv":{"point":0,"level":1},"card":"u674eu97e9u97e9","tags":"-1","flag":0,"nick":"u2581u2581u5e7bu68a6u541fu8ff7u60d1u4e0du4f4fu7684u5fc3","qage":8,"rm":1},{"uin":296915611,"role":2,"g":-1,"join_time":1595927320,"last_speak_time":1600572383,"lv":{"point":0,"level":1},"card":"u9b4fu5f3a","tags":"-1","flag":0,"nick":"u8defu4ebau7532@u63d0u4e0du8d77u52b2","qage":13,"rm":1}],"count":48,"svr_time":1600572532,"max_count":200,"search_count":48,"extmode":0}
    
    import jsonpath
    #返回max_count的值为200
    print(jsonpath.jsonpath(s,'$.max_count'))#返回的都是list
    #返回第一个mems的昵称
    print(jsonpath.jsonpath(s,'$.mems[0].nick'))
    #可以模糊匹配
    print(jsonpath.jsonpath(s,'$..level'))#取到所有leveld的值
    #返回search_count的值
    print(jsonpath.jsonpath(s,'$.search_count'))
    View Code

    五、my_db

    import pymysql
    from loguru import logger
    import traceback
    
    MYSQL_INFO = {
        'host':'118.24.3.40',
        'user':'jxz',
        'password':'123456',
        'db':'jxz',
        'charset':'utf8',
        'autocommit':True
    }
    class MySQL:
        def __init__(self,host,user,password,db,charset='utf8',autocommit=True):
            self.conn = pymysql.connect(user=user,host=host,password=password,db=db,charset=charset,autocommit=autocommit)
            self.cursor = self.conn.cursor()
    
    
        def __del__(self):
            self.__close()
    
        def execute(self,sql):
            try:
                self.cursor.execute(sql)
            except Exception:
                logger.error('sql执行出错,sql语句是{}',sql)
                logger.error(traceback.format_exc())
    
        def fetchall(self,sql):
            self.execute(sql)
            return self.cursor.fetchall()
    
        def fetchone(self,sql):
            self.execute(sql)
            return self.cursor.fetchone()
    
        def bak_db(self):
            pass
    
        def __close(self):
            self.cursor.close()
            self.conn.close()
    
    if __name__ == '__main__':
        my = MySQL(**MYSQL_INFO)
        print(my.fetchall('select * from app_myuser;'))
        my.fetchone('select * from app_myuser where id=1;')
        my.fetchone('select * from app_myuser where id=1;')
        my.fetchone('select * from app_myuser where id=1;')
    my_db

    六、面向对象

    #以前的#面向过程
    '''
    1.4s店看车,付钱
    2.保险公司
    3.车管所,办理临时拍照
    4.缴税
    5.车管所、上牌、行驶证
    调用a b c 函数
    执行者
    '''
    
    
    
    #面向对象==化零为整
    '''
    买车处->
    #1.4s店看车,付钱
    #2.保险公司
    # 3.车管所,办理临时拍照
    #4.缴税
    #5.车管所、上牌、行驶证
    调用car()
    指挥者
    '''
    '''
    类:一个模板,一个模型
    对象:根据模板造出来的具体的东西
    实例:根据模板造出来的具体的东西
    实例化:把模板做成具体东西的过程
    构造函数:类在实例化的时候,自动执行的函数2.如果要使用这个类,必须要传一些参数的时候,参数写在构造函数里面
    self,this:本类对象
    析构函数:实例被销毁的时候会自动执行
    私有:只能通过self调用,不能通过实例调用;只能在类里面用,不能在类外面用 def __close(self):
    类方法:公共的方法,直接可以通过类名来调用
    不需要实例化,通过实例也可以调用
    类变量:定义在类里面的变量
    实例方法:必须实例化的时候才可以调用,参数里有self
    静态方法:和一个普通的方法没有任何区别,和类也没有什么关系,只是定义在类里面而已
    属性方法:一个看起来像变量的方法
    继承:父子关系
    python中没有封装和多态
    面向对象的三大类型:封装、继承、多态(java强类型,python弱类型)
    '''
    #类名首字母大写,驼峰
    #函数名、变量名:xx_xx,下划线
    import time
    class PresonManger:#经典类
        pass
    
    class Person2():#新式类
        pass
    
    class Person3(object):#新式类
        pass
    
    #=================================
    class Person:#
        #类变量
        country = 'Chain'
        def __init__(self,name,sex,country='Chain'):
            # 构造函数:类在实例化的时候,自动执行的函数
            #变量中只要加了self之后,变量在这个类中所有函数都可以用
            print('self的内存地址', id(self))
            self.name = name
            self.sex = sex
            self.__height = 200
            self.country = country
            self.birthday = time.time()
            self.cry()
            # print('我是构造函数')
    
        def __del__(self):
            #最后执行析构函数
            print('我是析构函数%s'% self.name)
    
        @property  #不能有参数,必须有返回值
        def age(self):
            return int(time.tiem() - self.birthday)
    
        def run(self):
    
            print('%s run...'% self.name)
    
        def fly(self):
            print('%s fly'% self.name)
    
        def cry(self):
            print('%s 呜呜呜'% self.name)
    
        def say(self):#实例方法
            print('my name is %s,sex is %s '% (self.name,self.sex))
            print('%s 斤' %self.__height)
            print('我的国籍式%s'%self.country)
    
        @classmethod#类方法
        def putonghua(cls):
            print(cls.country)
            print('会说普通话')
    
        @staticmethod#静态方法
        def suangua():
            print('test')
    
    bm = Person('小黑','2.男')#实例化
    print('self的内存地址',id(bm))
    #bm 对象,实例
    bm.run()
    bm.country = 'Janpan'#类变量
    Person.country = 'Janpan'#类方法
    Person.putonghua()
    Person.suangua()
    Person.age#调用属性方法
    bm.suangua()
    bm.say()
    # print(bm.__height) #私有的不可以使用
    
    benz = Person('小白','')#实例化
    print('self的内存地址',id(benz))
    benz.fly() #相当于Person.fly(benz)
    benz.say()
    del bm
    print('abc/////////////')
    View Code

    七、继承:

    class Lw:
        def driver(self):
            print('开车')
    
        def make_money(self):
            print('挣5000钱')
    
    class Xw(Lw):
        #重写1:直接全部重写
        def driver(self):
            print('开飞机✈')
        #重写2:先调用之前的方法,然后在执行新增的方法
        def make_money(self):
            super().make_money()
            print('再5000块钱')
    
    a = Xw()
    a.driver()
    a.make_money()
    
    
    
    #======多态========
    class Car:#基类
        def __init__(self,name):
            self.name = name
    
        def run(self):
            print('%s run...' %self.name)
    
    class Bmw(Car):
        def fly(self):
            print('fly...')
    
    class Benz(Car):
        def swim(self):
            print('swim...')
    
    class Audi(Car):
        def liting(self):
            print('liting...')
    
    def run(obj):
        obj.run()
    
    c1 = Bmw('宝马')
    c2 = Benz('奔驰')
    c3 = Audi('奥迪')
    
    run(c1)
    run(c2)
    run(c3)
    
    class E:
        def daka(self):
            pass
    
    class E1:
        def daka(self):
            print('8:30')
    
    class E2:
        def daka(self):
            print('9:30')
    
    class E3:
        def daka(self):
            print('10:30')
    View Code

    八、总结:

  • 相关阅读:
    Analog power pin UPF defination
    动态功耗计算
    静态功耗 计算
    Innovus 对multibit 的支持
    P &R 12
    P & R 11
    power-plan如何定
    P & R 10
    P & R 9
    线程基础
  • 原文地址:https://www.cnblogs.com/victory-0315/p/13734308.html
Copyright © 2020-2023  润新知