美文网首页
python基础之类与对象的应用-操作excel

python基础之类与对象的应用-操作excel

作者: DayBreakL | 来源:发表于2019-10-07 01:26 被阅读0次

    python操作excel

    openpyxl

    • 前置说明

      • 安装openpyxl
      • 只支持.xlsx后缀
    • 创建excel

      • 手动创建:日常手动创建,双击excel图标
      • 代码创建:后面讲
    • 打开excel

      image
      from openpyxl import load_workbook
      # 1.打开excel
      wb=load_workbook("test.xlsx")
      # 2.定位表单
      sheet=wb["test001"] #必须传入表单名,返回表单对象
      # 3.定位但单元格 行列值
      value=sheet.cell(1,1).value #第1行第1列的单元格.值
      #打印单元格的值
      print(value)
      #最大行
      print("最大行:",sheet.max_row)
      #最大列
      print("最大列:",sheet.max_column)
      
    image
    • 数据从excel中拿出来是什么类型

      #数据从excel中拿出来是什么类型
      print("学号是:",sheet.cell(1,1).value,type(sheet.cell(1,1).value))
      print("分数是:",sheet.cell(1,2).value,type(sheet.cell(1,2).value))
      print("不及格率:",sheet.cell(1,3).value,type(sheet.cell(1,3).value))
      print("住址是:",sheet.cell(1,4).value,type(sheet.cell(1,4).value))
      

      结果是:数字还是数字,其他都是字符

      学号是: 18 <class 'int'>
      分数是: {"语文":90,"数字":98,"生物":78} <class 'str'>
      不及格率: 0.3 <class 'float'>
      住址是: 中国上海 <class 'str'>
      
    • eval() 把数据类型转换为原本的类型(仅限被转为字符串)

      s="True" #布尔值转为字符串
      print(type(s))  #<class 'str'>
      a=eval(s)#使用eval函数,将字符串类型转为原来的布尔类型
      print(type(a)) #<class 'bool'>
      
    • 封装一个获取excel值的工具类

      • 方法一:把数据一次取出,调用一次取出sheet所有数据(建议使用)

        from openpyxl import load_workbook
        class GetExcel:
            def __init__(self,file_name,sheet_name):
                self.file_name=file_name
                self.sheet_name=sheet_name
        
            def get_data(self):
                wb=load_workbook(self.file_name)
                sheet=wb[self.sheet_name]
                test_data=[] #每条数据要存在列表里
                for i in range(1, sheet.max_row+1):
                    sub_data={}
                    sub_data["age"]=sheet.cell(i,1).value
                    sub_data["score"]=sheet.cell(i,2).value
                    sub_data["percent"]=sheet.cell(i,3).value
                    sub_data["local"]=sheet.cell(i,4).value
                    test_data.append(sub_data)
                return test_data
        
        ex=GetExcel("test.xlsx","test001")
        print("测试数据:",ex.get_data())
        
      • 方法二:数据需要的时候再调用,调用一次取出一个单元格数据

        ```
        from openpyxl import load_workbook
        class DoExcel:
            """
            获取excel单元格的值
            """
            def __init__(self,file_name,sheet_name):
                """
                
                :param file_name: excel文件名
                :param sheet_name: sheet名
                """
                self.file_name=file_name
                self.sheet_name=sheet_name
        
            def get_excel(self,i,j):
                """
                
                :param i: 第几行
                :param j: 第几列
                :return: 返回对应单元格的值
                """
                wb=load_workbook(self.file_name)
                sheet=wb[self.sheet_name]
                return sheet.cell(i,j).value
            
             def get_max_row(self):
                """
                :return: sheet的最大行数
                """
                return self.sheet_obj.max_row
    
            def get_max_col(self):
                """
                :return: sheet的最大列数
                """
                return self.sheet_obj.max_column
                
        if __name__ == '__main__': #测试
            do=DoExcel("test.xlsx","test001")
            print(do.get_excel(1,1))
        ```
    

    ddt

    • 安装ddt

    • ddt+unittest进行数据处理

      • 装饰器,暂时不用过多了解,不影响函数的情况下运行

      • ddt示例

        • @ddt 装饰测试类
        • @data 传入数据
        • @unpack 针对拿到的每一条数据,根据逗号进行拆分
        from ddt import ddt,unpack,data #导入ddt
        import unittest
        
        test_data=[1,4] #测试数据
        test_body=[[3,4],[2,3]]
        test_param=[[3,4],[2,3,7]]
        test_dict=[{"no":1,"name":"anny"},{"no":2,"name":"liu"}]
        
        @ddt #装饰测试类
        class TestMath(unittest.TestCase):
        
            @data(test_data)
            def test_print_data(self,item): #一条用例
                print("item:",item) #item: [1, 4]
                
            @data(*test_data) #装饰测试方法,拿到几条数据执行几条用例
            #不定长参数,俗称:脱外套
            def test_print_data_01(self,item):
                print("item:", item)  # item: 1  item: 4
            
            @data(*test_body) #脱外套只脱一层
            def test_print_data_02(self,item):
                print("item:",item) #item: [3, 4]  item: [2, 3]
                
            @data(*test_body)
            @unpack #针对拿到的每一条数据,根据逗号进行拆分,
            def test_print_data_03(self,a,b): #参数个数对应@npack拆分的个数,否则会报错
                print("a:",a)
                print("b:",b)
            # 输出: 
            # a: 3 b: 4
            # a: 2 b: 3
            
            
            @data(*test_param)
            @unpack
            #对于每一条测试用例的数据不等长时,可以采用默认值为None的方式接收避免报错
            def test_print_data_04(self,a=None,b=None,c=None):
                print("a:",a)
                print("b:",b)
                print("c:",c)    
            
            # 输出:
            # a: 3 b: 4 c: None
            # a: 2 b: 3 c: 7
            
            @data(*test_dict)
            @unpack
            #对字典进行unpack,参数名与你的字典key对应
            def test_print_data_05(self,no,name):
                print("no:",no)
                print("name:",name)
        
        • 使用unpack,data里的参数记得加*
        • 参数数据过长时,不建议用@unpack@data拿到后根据索引取值
        • 光标放在代码最后面再run,不然会报错
        • 对字典进行unpack,参数名与你的字典key对应

    DDT与excel结合使用

    • 加载测试用例时,要使用TestLoader方法加载

    总结unittest+excel

    • 两种方式
      • 超继承
      • ddt
    • 思路
      • 自己写的类
      • unittest单元测试:实现对自己写的类的测试
      • TestCase测试用例:self.assert断言、异常处理
      • 参数化:数据可以写在代码里,也可以写在excel里,excel使用openpyxl
        • 处理数据写成类 class GetExcel:
      • 数据与unittest结合起来
        • 超继承(原理要懂)
        • ddt (推荐使用)

    配置文件

    用例的可配置

    有时,我们需要run不同程度的case、不同模块的case,所以需要case的一个可配置性

    image
    from openpyxl import load_workbook
    class GetExcel:
        def __init__(self,file_name,sheet_name):
            self.file_name=file_name
            self.sheet_name=sheet_name
    
        def get_data(self,button="all"):
            """
            约定参数button,默认值为all。
            如果button值为“all”,则表示运行所有的case;
            如果button的值为一个case_id的列表,按照列表里的case_id进行运行。
            """
            wb=load_workbook(self.file_name)
            sheet=wb[self.sheet_name]
            test_data=[] #每条数据要存在列表里
            for i in range(2, sheet.max_row+1): #第一行是title,所以从第二行开始
                sub_data={}
                sub_data["case_id"] = sheet.cell(i, 1).value
                sub_data["mouble"] = sheet.cell(i, 2).value
                sub_data["age"]=sheet.cell(i,3).value
                sub_data["score"]=sheet.cell(i,4).value
                sub_data["percent"]=sheet.cell(i,5).value
                sub_data["local"]=sheet.cell(i,6).value
                test_data.append(sub_data)
            #对传入的button值进行判断
            if button == "all":
                finally_data=test_data
            else: #[1,2,3,4]
                finally_data=[]
                for item in test_data:
                    if item["case_id"] in button:
                        finally_data.append(item)
            return finally_data
    
    if __name__ == '__main__':
        ex=GetExcel("testdata.xlsx","Sheet1")
        print("测试数据:",ex.get_data()) #所有数据
        print("测试数据:", ex.get_data([1,3])) #第一条、第三条测试数据
    
    配置文件

    平常工作中可能会常见到.properties .config .ini .log4j(.log4j是java中的配置文件,python不用)结尾的文件,这些都是配置文件。python中有configparser模块可以去读取配置信息

    • 配置文件的规范

      • 新建一个文件以.config结尾,.properties.ini都可以
      • section 片段,配置文件中用[]区分,表示不同区域的数据
      • option=value,键值对,相当于key:value
      #case.config文件
      
      [BUTTON] #section
      button=all #option=value
      
      [PYTHON11] #section
      num=30  #option、value
      monitor=小月 #option=value 
      
    • 读取配置文件

      import configparser
      
      cf=configparser.ConfigParser()
      cf.read("case.config",encoding="utf-8")
      
      #获取配置文件的数据
      # 方法一
      res_1=cf.get("BUTTON","button") #(section,option)获取对应option的value
      print(res_1) #all
      # 方法二
      res_2=cf["BUTTON"]["button"]
      print(res_2) #all
      
      #获取所有的section
      res_3=cf.sections()
      print(res_3) #['BUTTON', 'PYTHON11']
      
      #获取option和value,每对以元组形式返回在一个列表里
      res_4=cf.items("PYTHON11")
      print(res_4) #[('num', '30'), ('monitor', '小月')]
      
    • 数据类型

      直接获取的数据类型都是字符串,使用eval()转换为原始数据类型

      res_1 = cf.get("BUTTON", "button")
      print(type(res_1)) #<class 'str'>
      res_2=cf.get("PYTHON11", "num")
      print(type(res_2)) #<class 'str'>
      
      #使用eval()转换为原始数据类型
      res_3 =cf.get("python11", "num")
      print(type(eval(res_3)))
      
    • 封装为一个工具类

      • tools文件夹中写入配置文件case.config
        [BUTTON]
        button=all
        #button=[1,2]
        
        
      • tools文件夹中写一个工具类class ReadConfig:
        import configparser
        
        class ReadConfig:
            def read_config(self,file_name,section,option):
                cf=configparser.ConfigParser()
                cf.read(file_name,encoding="utf-8")
                return eval(cf.get(section,option))
        
        
        if __name__ == '__main__':
            rc=ReadConfig()
            res=rc.read_config("case.config","BUTTON","button")
            print(res) #all
        
      • 原来的do_excel工具类要加以修改,加入读取配置文件
        from openpyxl import load_workbook
        from API_AUTO.tools import read_config
        
        class GetExcel:
            def __init__(self,file_name,sheet_name):
                self.file_name=file_name
                self.sheet_name=sheet_name
        
        def get_data(self):
            #读取配置文件
            button=read_config.ReadConfig().read_config("case.config","BUTTON","button")
            wb=load_workbook(self.file_name)
            sheet=wb[self.sheet_name]
            test_data=[] #每条数据要存在列表里
            for i in range(2, sheet.max_row+1):
                sub_data={}
                sub_data["case_id"] = sheet.cell(i, 1).value
                sub_data["mouble"] = sheet.cell(i, 2).value
                sub_data["age"]=sheet.cell(i,3).value
                sub_data["score"]=sheet.cell(i,4).value
                sub_data["percent"]=sheet.cell(i,5).value
                sub_data["local"]=sheet.cell(i,6).value
                test_data.append(sub_data)
        
            if button == "all":
                finally_data=test_data
            else: #[1,2,3,4]
                finally_data=[]
                for item in test_data:
                    if item["case_id"] in button:
                        finally_data.append(item)
            return finally_data
        
        if __name__ == '__main__':
        
            ex=GetExcel("testdata.xlsx","Sheet1")
            print("测试数据:",ex.get_data())
        
        这样根据给配置文件button配置不同的值,all或者case_id的列表,run不同的数据。

    相关文章

      网友评论

          本文标题:python基础之类与对象的应用-操作excel

          本文链接:https://www.haomeiwen.com/subject/vgmppctx.html