zoukankan      html  css  js  c++  java
  • 五、python-jsonpath、写日志、面向对象

    (一)jsonpath

     1、python需安装jsonpath模块

    # 安装
    pip install jsonpath

    2、jsonpath使用

    (1)模块导入使用:

    # 模块提取方法
    import json
    from jsonpath import jsonpath

    (2)语法规则

    JSONPath Xpath 描述
    $ / 根节点
    @ . 过滤器断言(filter predicate)处理的当前节点对象,类似于this
    .or[] / 取子节点
    n/a ..

    父元素,Jsonpath未支持

    .. // 递归搜索,不管位置,选择所有符合条件的条件
    * * 通配符,匹配所有的元素
    n/a @ 属性访问字符,JsonPath不支持
    [] [] 迭代器标示(可以在里面做简单的迭代操作,如数组下标,根据内容选值等)
    [,] l 连接操作符在XPath结果合并其它节点集合。JsonPath允许name或者数组索引
    ?() [] 应用过滤表示式,可进行过滤操作
    () n/a 脚本表达式,使用在脚本引擎下面,XPath不支持
    [start:end:step] n/a 数组分割操作,XPath不支持
    n/a () Xpath分组,JsonPath不支持

    注意:

    • []在Xpath表达式总是从前面的路径来操作数组,索引是从1开始;
    • 使用JsonPath的[]操作符操作一个对象或者数组,索引是从0开始的。

    (3)实例:https://qun.qq.com/cgi-bin/qun_mgr/search_group_members

    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":1600967808,"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":0},{"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":0},{"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":0},{"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":0},{"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":0},{"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":0},{"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":0},{"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":0},{"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":0},{"uin":635763064,"role":2,"g":1,"join_time":1592997221,"last_speak_time":1600596210,"lv":{"point":0,"level":1},"card":"u970du7d2bu9633","tags":"-1","flag":0,"nick":"u6f02u6d41u6d77u5cb8","qage":13,"rm":0},{"uin":857566034,"role":2,"g":1,"join_time":1593329449,"last_speak_time":1600587021,"lv":{"point":0,"level":1},"card":"u4ee3u723d","tags":"-1","flag":0,"nick":"u767du7fbdu5f52u697c","qage":13,"rm":0},{"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":0},{"uin":704096641,"role":2,"g":1,"join_time":1594023174,"last_speak_time":1600588791,"lv":{"point":0,"level":1},"card":"u803fu5a1f","tags":"-1","flag":0,"nick":"704096641","qage":13,"rm":0},{"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":0},{"uin":799614279,"role":2,"g":0,"join_time":1594884719,"last_speak_time":1600575331,"lv":{"point":0,"level":1},"card":"u9c81u6d25u5065","tags":"-1","flag":0,"nick":"u4e28u5bd2u5c10u6708u309e","qage":13,"rm":0},{"uin":695254152,"role":2,"g":0,"join_time":1594886366,"last_speak_time":1600596152,"lv":{"point":0,"level":1},"card":"u738bu7965u9f99","tags":"-1","flag":0,"nick":"u8ffdu68a6u8d64u5b50u5fc3","qage":13,"rm":0},{"uin":251202767,"role":2,"g":1,"join_time":1594943472,"last_speak_time":1600596158,"lv":{"point":0,"level":1},"card":"u9ad8u96ef","tags":"-1","flag":0,"nick":"u7d2bu8272u7cbeu7075","qage":16,"rm":0},{"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":0},{"uin":357084975,"role":2,"g":1,"join_time":1595817181,"last_speak_time":1600596163,"lv":{"point":0,"level":1},"card":"u674eu97e9u97e9","tags":"-1","flag":0,"nick":"u2581u2581u5e7bu68a6u541fu8ff7u60d1u4e0du4f4fu7684u5fc3","qage":8,"rm":0},{"uin":296915611,"role":2,"g":-1,"join_time":1595927320,"last_speak_time":1600874827,"lv":{"point":0,"level":1},"card":"u9b4fu5f3a","tags":"-1","flag":0,"nick":"u8defu4ebau7532@u63d0u4e0du8d77u52b2","qage":13,"rm":0}],"count":48,"svr_time":1601129005,"max_count":200,"search_count":48,"extmode":0}
    
    import jsonpath
    # jsonpath取层级比较多,复杂的方式
    print(jsonpath.jsonpath(s,'$.max_count'))
    print(jsonpath.jsonpath(s,'$.mems[0]'))
    print(jsonpath.jsonpath(s,'$.mems[0].nick'))
    print(jsonpath.jsonpath(s,'$..level'))

    执行结果如图:

    (二)写日志:为了方便排查问题

    1、Python自带的logging不是很好用,建议安装模块:loguru

    # 安装loguru模块
    
    pip install loguru

    2、导入loguru模块 

    # import logging  # python自带模块
    # import loguru
    from loguru import logger
    # debug      打印日志比较详细,调试信息,最低的级别
    # info       正常的提示信息
    # warning    警告信息
    # error      出错了
    # exception  程序出异常了 SQL执行出错
    
    import  sys
    def Bob():
        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)  # print,输出,本地运行的时候,在控制台打印
        # logger.add('abc.log',level='INFO',encoding='utf-8',enqueue=True) # 写在日志文件里面
    # enqueue=True ,异步写日志
    logger.debug('程序开始运行了') logger.debug('开始连接MySQL') logger.info('MySQL配置XXXX') logger.warning('警告,磁盘空间即将不足!') logger.error('程序出错了!') Bob()

    执行结果如图:

     3、定义写日志函数:

    (1)同步写日志

    # 同步写日志
    def write_log(msg):
        with open('a.log','a',encoding='utf-8') as fw:
            fw.write(msg)

    (2)异步写日志

    from loguru import logger
    import  sys
    def Bob():
        logger.remove() # 清除以前它的默认设置
        fmt = '[{time}][{level}][{file.path}:{line}:function_name:{function}] || msg = {message}'  # level file function module time message
        logger.add(sys.stdout,level='INFO',format=fmt)  # print,输出 本地运行的时候,在控制台打印
        logger.add('abc.log',level='DEBUG',encoding='utf-8',enqueue=True,rotation='1 kb') # 写在日志文件里面
    
        # logger.add("demo1.log",rotation="500 MB") # 文件过大就会重新生成一个文件
        # logger.add("demo2.log",rotation="01:00")  # 每天1点创建新文件
        # logger.add("demo3.log",rotation="2 week") # 文件时间过长就会创建新文件
        # logger.add("demo4.log",retention="7 days") # 一个礼拜后会清空
        # enqueue=True,异步写日志
        
         for i in range(100):
            logger.debug('程序开始运行了')
            logger.debug('开始连接MySQL')
            logger.info('MySQL配置XXXX')
            logger.warning('警告,磁盘空间即将不足!')
            logger.error('程序出错了!')   
    
    Bob()

    (3)rotation和retention

    • rotation 可以设置大小,超过多大就产生一个新文件 1 kb,500 m,1 g
    • rotation 可以多长时间,1 day 1 hour
    • rotation 几点创建新文件,00:00 1:00
    • retention 多长时间清空日志

    (三)面向对象

    1、面向对象:定义类

    (1)类(class)、类变量、数据成员、方法重写、局部变量、实例变量、对象、实例、实例化、继承、方法

       类:用来描述具有相同的属性和方法的对象的集合。对象是类的实例。一个模板,一个模型。例如:Class Car

      类变量:定义在类中且在函数体之外。类变量通常不作为实例变量使用。

      数据成员:类变量或者实例变量,用于处理类及其实例对象的相关的数据。

      方法:类中定义的函数。

      方法重写:从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称方法的重写。

      局部变量:定义在方法中的变量,只作用于当前实例的类。

      实例变量:在类的声明中,属性是用变量来表示的。这种变量就成为实例变量。

      对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。根据模板创造出来的具体的东西。例如:BMW为对象,实例

      实例:根据模板创造出来的具体的东西。例如:BMW=Car()实例化

      构造函数:

          A:类在实例化的时候,自动执行的函数

          B:如果要使用这个类,必须传一些参数写在构造函数里面

      实例化:创建一个类的实例,类的具体对象。把模板做成具体东西的过程  

      继承:一个派生类(derived class)继承基类(base class)的字段和方法。

    # 1、经典类
    class PersonManager:  
        pass
    
    # 2、新式类
    class Person2():
        pass
    
    # 3、新式类
    class Person3(object):
        pass

    (2)实例,定义一个汽车类,且再定义方法

    # 定义一个汽车类,并且定义方法
    class Car:
        def run(self):
            print('run..')
    
        def baoyang(self):
            print('payfor')
    
    BMW = Car()
    BMW.run()
    BMW.baoyang()

    运行结果为:

    (3)定义一个类:Person

    class Person:
        def __init__(self,name,sex):
            # 构造函数,自动执行函数
            self.name = name
            self.sex = sex
            self.cry()
            print('我是构造函数')
    
        def eat(self):
            print('%s 在eating..' % self.name)
    
        def make(self):
            print('%s 在making..'% self.name)
    
        def say(self):
            print('my name is %s, sex is %s' %(self.name,self.sex))
    
        def cry(self):
            print('%s 哇哇哇哇'% self.name)
    
    Nancy = Person('Nancy','Female')
    Bob = Person('Bob','male')
    Nancy.eat()
    Bob.cry()

    (4)基础重载方法

    序号 方法,描述,简单的调用
    1

    _init_(self[,args...])

    构造函数

    简单的调用方法:obj = className(args)

    2

    _del_(self)

    析构方法,删除一个对象

    简单的调用方法:del obj

    3

    _repr_(self)

    转化为供解释器读取的形式

    简单的调用方法:repr(obj)

    4

    _str_(self)

    用于将值转化为适于人阅读的形式

    简单的调用方法:str(obj)

    5

    _cmp_(self,x)

    对象比较

    简单的调用方法:cmp(obj,x)

     (5)类的私有属性

      _private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。类内部的方法中使用时self._private_attrs。

    (6)单下划线、双下划线、头尾双下划线说明:

    • _foo_:定义的是特殊方法,一般是系统定义名字,类似_init_()之类的
    • _foo:以单下划线开头的表示的是protected类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于from module import*
    • __foo:双下划线表示的是私有类型(private)的变量,只能是允许这个类本身进行访问了。

    2、析构函数和构造函数,以及私有

    实例:

    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(host=host,user=user,password=password,db=db,charset=charset,autocommit=autocommit)
            self.cursor = self.conn.cursor()
    
        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)
        my.fetchall('select * from app_myuser;')
        my.fetchone('select * from app_myuser where id = 1;')
        my.execute('delete from user where id = 1;')
        my.close()

    析构函数:实例被销毁的时候自动执行的函数。最后执行析构函数。

    # 析构函数
    class Person:
        def __init__(self,name,sex):
            # 构造函数
            self.name = name
            self.sex = sex
            self.cry()
            print('我是构造函数')
    
        def __del__(self):
            print('我是析构函数')
    
        def eat(self):
            print('%s 在eating..' % self.name)
    
        def make(self):
            print('%s 在making..'% self.name)
    
        def say(self):
            print('my name is %s, sex is %s' %(self.name,self.sex))
    
        def cry(self):
            print('%s 哇哇哇哇'% self.name)
    
    Nancy = Person('Nancy','Female')
    Bob = Person('Bob','male')
    Nancy.eat()
    Bob.cry()

    私有:只能通过self调用,不能通过实例调用。

       只能在类里面用,类外面不能用。

       自己定义的方法和变量,如果是__开头,就是私有的

     3、各种方法类型

    (1)类方法:公共的方法,直接可以通过类名来调用,不需要实例化,通过实例也可以调用(@classmethod)

        @classmethod
        # cls代表类方法
        def English(cls):
            print('会说英语!')
    
    Person.English()

    (2)类变量:定义在类里面的变量

    class Person:
        country = 'China'
        def __init__(self,name,sex):
            self.name=name
            self.sex=sex
    
        def say(self):
            print('my name is %s, sex is %s' % (self.name, self.sex))
            print('我的国籍是 %s' % self.country)
    Amy = Person('Amy','')
    Amy.say()

    执行结果为:

    (3)实例变量(成员变量):self.XXX

    class Person:
        country = 'China'
        def __init__(self,name,sex):
            self.name=name
            self.sex=sex
    
        def say(self):
            print('my name is %s, sex is %s' % (self.name, self.sex))
            print('我的国籍是 %s' % self.country)
    Amy = Person('Amy','')
    Bob = Person('Bob','')
    Bob.country='UK'
    Amy.say()
    Bob.say()

    执行结果为:

    (4)静态方法(静态变量):和一个普通方法没有任何区别,和类也没有什么关系,只是定义在类里面(@staticmethod)

    @staticmethod
        def test():
            print('小测试')

    实例如下:

    class Person:
        country = 'China'
        def __init__(self,name,sex):
            self.name=name
            self.sex=sex
    
        def say(self):
            print('my name is %s, sex is %s' % (self.name, self.sex))
            print('我的国籍是 %s' % self.country)
    
        @classmethod
        # cls代表类方法
        def English(cls):
            print('会说英语!')
    
        @staticmethod
        def test():
            print('小测试')
    Person.test()
    Person.English()
    Amy = Person('Amy','')
    Bob = Person('Bob','')
    Bob.country='UK'
    Amy.say()
    Bob.say()
    Bob.test()

    执行结果如下:

     (5)属性方法:看起来像变量的方法,没有参数(@property)

    import time
    class Person:
        country = 'China'
        def __init__(self,name,sex):
            self.name=name
            self.sex=sex
            self.birthday=time.time()
    
        @property
        def age(self):
            return time.time() - self.birthday
    Amy = Person('Amy','')
    print(Amy.age)

    (6)实例方法:必须通过实例化才可以调用,只要参数有self

    4、面向对象的3大特性:封装、继承、多态

    (1)封装:把零散的代码封装到一起,化零为整

    (2)继承:用来节省代码

    实例:

    class Plant:
        def trees(self):
            print('这是一颗大树!')
        def origion(self):
            print('来着于云南省')
    # yangshu继承Plant类
    class yangshu(Plant):
        pass
    
    a = yangshu()
    a.trees()
    a.origion()

    执行结果如下:

    (3)多态:Python里面根本不需要多态

    (4)继承之重写:

    A:重写-直接覆盖

    class Plant:
        def trees(self):
            print('这是一颗大树!')
        def origion(self):
            print('来着于云南省')
    # yangshu继承Plant类
    class yangshu(Plant):
        # 重写
        def origion(self):
            print('来着于东北省')
    
    a = yangshu()
    a.trees()
    a.origion()

    执行结果为:

     

     B:重写-父用

    class Plant:
        def trees(self):
            print('这是一颗大树!')
        def origion(self):
            print('来着于云南省')
    # yangshu继承Plant类
    class yangshu(Plant):
        # 重写-覆盖
        def origion(self):
            # super 找到父类,调用再定义
           super().origion()
           print('来着于北京市')
    
    a = yangshu()
    a.trees()
    a.origion()

    5、实例:

    import os
    import requests
    
    max_count = 1000
    size = 40
    bkn = '2140990271'
    cookies = 'pgv_pvi=328774656; RK=Bqzk3YEWb+; ptcz=4c3263932d8d5a48b929cd2283f1bde3146c1ee5c4f104796f0c8d95df45c3c8; tvfe_boss_uuid=7d887b37fe60ad85; pgv_pvid=3957380448; _qpsvr_localtk=0.9320463335905909; uin=o1270894070; skey=@78hV4b1qu; p_uin=o1270894070; pt4_token=taQ**Bbk0PIr3PB*-*yZeg*Fq8ENsjSXEeEf3Y-9m94_; p_skey=VJFMRPfcF8O-aOhbyYT*g0zfuIhUCzLdT175dWC8CzU_; traceid=f656b26bcb'
    dir_name = 'qq_pics'
    
    class DownLoadQQGroupMemberPic:
        group_member_url = 'https://qun.qq.com/cgi-bin/qun_mgr/search_group_members'
        pic_url = 'https://q4.qlogo.cn/g?b=qq&nk=%s&s=140'
    
        def __init__(self, gc):
            self.gc = gc
            self.mkdir()
    
        def mkdir(self):
            if not os.path.exists(self.dir_name):
                os.mkdir(self.dir_name)
    
        def get_member_info(self, gc, st, end):
            # 获取群成员的信息
            data = {'gc': gc, 'st': st, 'end': end, 'bkn': bkn}
            headers = {'cookie': cookies}
            r = requests.post(self.group_member_url, data, headers=headers)
            members = r.json
            return members
    
        def save_picture(self, name, content):
            with open(name + '.jpg', 'wb') as fw:
                fw.write(content)
    
        def download_picture(self, qq):
            r = requests.get(self.pic_url % qq)
            return r.content
    
        def down_qq_pic(self, mems):
            for m in mems:
                qq = m.get('uin')
                name = m.get('card') if m.get('card') else m.get('nick')
                content = self.download_picture(qq)
                self.save_picture(name, content)
    
        def main(self):
            count = 0
            for j in range(0, self.max_count + 1, self.size):
                mems = self.get_member_info(self.gc, j + count, j + self.size + count)
                if 'mems' in mems:
                    self.down_qq_pic(mems)
    温故而知新
  • 相关阅读:
    Day6
    Day6
    Day6
    Day6
    Day6
    Day6
    LeetCode "The Skyline Problem"
    HackerRank
    HackerRank
    HackerRank
  • 原文地址:https://www.cnblogs.com/krystal-xiao/p/13724538.html
Copyright © 2011-2022 走看看