python 文件读写方法汇总

一、表格读写

所有可使用的表格读写库 Python Resources for working with Excel - Working with Excel Files in Python

1、excel表格读取 使用xlrd

# _*_ conding:utf-8 _*_
import xlrd


book = xlrd.open_workbook("./a.xlsx")  # 读取表格文件
print(book.sheet_names())  # 所有的sheet的名字
# sheet = book.sheet_by_name('Sheet1')  # 通过sheet名获取指定sheet数据
sheet = book.sheet_by_index(0)  # 通过sheet下标获取指定sheet数据
print(sheet.name)  # sheet名
print(sheet.nrows)  # 指定sheet的总行数
print(sheet.ncols)  # 指定sheet的总列数

# 按行输出
for r in range(sheet.nrows):
    print(sheet.row(r))  # 第几行

# # 按列输出
for i in range(sheet.ncols):
    print(sheet.col(i))  # 第几列

print(sheet.row_values(rowx=0, start_colx=0, end_colx=-1))  # 第几行内 从第几列开始到第几列结束
print(sheet.row_values(rowx=sheet.nrows-1, start_colx=0, end_colx=-1))  # 第几行内 从第几列开始到第几列结束
print(sheet.cell_value(rowx=0, colx=0))  # 第几行 第几列的值
print(sheet.cell(rowx=2, colx=1))  # 第几行 第几列的某个值的类型和具体数值
print(sheet.row_len(rowx=1))  # 指定行数的字段数量
print(sheet.col(colx=0, start_rowx=0, end_rowx=-1))  # 指定列的类型及具体值   [text:'类目', text:'一年级', text:'二年级']
print(sheet.col_values(colx=0, start_rowx=0, end_rowx=sheet.row_len(rowx=0)+1))  # 指定列的指定行范围数据

2.excel表格写  使用 openpyxl库

官方文档:openpyxl - A Python library to read/write Excel 2010 xlsx/xlsm files — openpyxl 3.0.9 documentation

# _*_ coding:utf-8 _*_
import openpyxl


wb = openpyxl.Workbook()

sheet1 = wb.active
sheet1.title = "test"  # sheet名
sheet1['C5'] = "张三"  # 指定位置赋值

sheet2 = wb.create_sheet(title="test1")  # 创建sheet
sheet2['A1'] = '小明'
sheet2.cell(row=2, column=1, value='测试')  # 指定位置赋值
wb.save(filename="b.xlsx")  # 保存

 方法封装

#! /usr/bin/python3
# -*- coding: utf-8 -*-
# @Time: 2022/2/22 14:21
# @Author: 一碗烈酒
import openpyxl
import os


class ExcelUtil:
    def __init__(self, file_name: str, mode: str = "r"):
        """
        :param file_name: 文件路径
        :param mode: 模式。 r: 读文件; w:写文件
        """
        # 文件前置处理
        self.file_name = self._file_preprocess(file_name)
        if mode == "w":
            self._create_new_excel(self.file_name)
        self.work_book = openpyxl.load_workbook(self.file_name)

    def _file_preprocess(self, file_name: str, mode: str = "r"):
        """
        文件前置处理。修正文件后缀名;目录不存在则创建目录,文件不存在则创建一各空的表格
        :param file_name: 文件路径
        :param mode: 是读取文件还是写入文件 :r, w
        :return: 文件绝对路径
        """
        # 将文件路径转换为绝对路径,防止因为平台不同导致路径分隔符不一致的问题
        file_name = os.path.abspath(file_name)
        # 检查文件后缀名是否正确
        if os.path.splitext(file_name)[-1] != ".xlsx":
            if mode == "r":
                # 方案一:直接抛异常
                raise NameError("文件后缀名不正确!需要 .xlsx 但是提供了 {}".format(os.path.splitext(file_name)[-1]))
            if mode == "w":
                # 方案二:修改正确的文件后缀名
                file_name = os.path.join(os.path.split(file_name)[0],
                                         os.path.splitext(os.path.split(file_name)[-1])[0] + ".xlsx")
        # # 检查目录是否存在,不存在则新建
        # if not os.path.exists(os.path.split(file_name)[0]):
        #     os.makedirs(os.path.split(file_name)[0])
        # # 检查文件是否存在,不存在,创建一个空的文件
        # if not os.path.exists(file_name):
        #     self._create_new_excel(file_name)
        return file_name

    def _create_new_excel(self, file_name: str, default_sheet_name: str = "Sheet"):
        """
        创建一个空的Excel文件
        :param file_name: 文件名,包含路径
        :param default_sheet_name: 默认sheet名
        :return: 创建成功返回True, 创建失败返回 False
        """
        # 检查目录是否存在,不存在则新建
        if not os.path.exists(os.path.split(file_name)[0]):
            os.makedirs(os.path.split(file_name)[0])
        # 检查文件是否存在,不存在,创建一个空的文件
        if not os.path.exists(file_name):
            self._create_new_excel(file_name)
        # 新建并保存excel
        new_workbook = openpyxl.Workbook()
        default_sheet = new_workbook.active
        default_sheet.title = default_sheet_name
        new_workbook.save(file_name)
        return True

    def get_sheetnames(self):
        """
        读取文件的 sheet名列表
        :param file_name: 文件路径
        :return: sheet名列表
        """
        return self.work_book.sheetnames

    def get_sheet_data_row_by_row(self, sheet_name: str, rows: str = "all"):
        """
        逐行读取Excel文件,返回指定sheet下的全部数据。
        :param sheet_name: sheet名
        :return: 全部数据。包括 (表头[]和数据[[], []])
        """
        sheet = self.work_book[sheet_name]
        values = []
        if rows == "all":
            rows = sheet.max_row
        cols = sheet.max_column
        for row in range(1, rows + 1):
            rows_value = []
            for col in range(1, cols + 1):
                rows_value.append(sheet.cell(row, col).value)
            values.append(rows_value)
        return values[0], values[1:]

    def get_column_data(self, sheet_name: str, column: int, start_row: int = 2):
        """
        读取第几列的数据
        :param sheet_name: 指定sheet名称
        :param col: 指定第几列
        :param start: 从第几行开始读取,默认第二行
        :return: list格式指定列的数据
        """
        cols = []
        sheet = self.work_book[sheet_name]
        for i in range(start_row, sheet.max_row + 1):
            cols.append(sheet.cell(i, column).value)
        return cols

    def get_row_data(self, sheet_name: str, row: int, start_column: int = 2):
        """
        读取第几行的数据
        :param sheet_name: 指定sheet名称
        :param row: 指定第几行
        :param start_column: 从第几列开始读取,默认第二列
        :return: list格式指定行的数据
        """
        rows = []
        sheet = self.work_book[sheet_name]
        for col in range(start_column, sheet.max_column + 1):
            rows.append(sheet.cell(row, col).value)
        return rows

    def get_all_rows(self, sheet_name: str, start_column: int = 2):
        """
        逐行读取数据,返回全部数据。读取指定sheet的数据,默认从第二列开始读取
        :param sheet_name: sheet名
        :param start_column: 开始读取的列,默认从第二列开始读取
        :return: [[],[]] 逐行读取的数据列表
        """
        datas = []
        for row in range(start_column, self.work_book[sheet_name].max_row + 1):
            datas.append(self.get_row_data(sheet_name, row, start_column))
        return datas

    def get_all_columns(self, sheet_name: str, start_row: int = 2):
        """
        逐列读取数据,返回全部数据,读取指定sheet的数据,默认从第二行开始读取
        :param sheet_name: sheet名
        :param start_row: 开始读取的行,默认从第二行开始读取
        :return: [[],[]] 伫列读取的数据列表
        """
        columns = []
        sheet = self.work_book[sheet_name]
        for i in range(start_row, sheet.max_row + 1):
            columns.append(self.get_column_data(sheet_name, i, start_row))
        return columns

    def write_new_excel_row_by_row(self, sheet_name: str, row_values: list):
        """
        写入数据到一个新的表格中。
        :param sheet_name: sheet名
        :param row_values: 数据 格式:[[row1column1, row1column2, row1column3], [row2column1, row2column2, row2column3], [row3column1, row3column2, row3column3], ]
        :return:
        """
        worksheet = self.work_book[sheet_name]
        worksheet.title = sheet_name
        for row in row_values:
            worksheet.append(row)
        self.work_book.save(self.file_name)
        return True


if __name__ == "__main__":
    # 读文件
    ## excel = ExcelUtil("./aaa/bbb/tmp11.xlsxss")  # 这个会报错,因为默认实例是读取文件,然而文件后缀又不对,所以会抛异常
    excel_read = ExcelUtil("tmp.xlsx", mode="r")
    print(excel_read.get_sheetnames())
    print(excel_read.get_row_data(excel_read.get_sheetnames()[0], row=1, start_column=1))
    print(excel_read.get_column_data(excel_read.get_sheetnames()[0], column=1, start_row=1))
    print(excel_read.get_all_rows(excel_read.get_sheetnames()[0], start_column=1))
    print(excel_read.get_all_columns(excel_read.get_sheetnames()[0], start_row=1))
    print(excel_read.get_sheet_data_row_by_row(excel_read.get_sheetnames()[0]))

    # 写文件
    # excel_writer = ExcelUtil("tmp.xlsx", mode="w")
    # excel_writer.write_new_excel_row_by_row(sheet_name=excel_writer.get_sheetnames()[0], row_values=[[1, 2, 3], [4, 5, 6]])

二、TXT文件读写

# 读写模式:w:写入新文件,r:读取已有文件,wb:二进制写入,rb:二进制读取,a+:追加,
# 写入文件
with open("./c.txt", "a+", encoding="utf-8") as f:
    f.write("\n你是我的小呀小苹果\thaha")


# 读取文件
with open("./c.txt", "r", encoding="utf-8") as f:
    print(f.read())  # 读取所有值,作为一个字符串返回
    # print(f.readline())  # 读取一行值,再次调用时从本次读取位置继续下一行读取
    # print(f.readlines())  # 读取所有值 列表格式,每行一个字符串

三、csv文件读写

 csv 方法 封装

import csv
import codecs

class Csv:
    def __init__(self, filename):
        self.filename = filename

    def write_dict(self, field_titles, values):
        """
        将字典格式的数据列表写入到csv文件
        :param field_titles: 文件表头 格式:可迭代对象均可 示例:["id", "name"]
        :param values: 文件数据 格式:[{}, {}] 示例:[{"id": 1, "name": "a"}, {"id": 2, "name": "b"}]
        :return: True
        """
        with open(self.filename, "w", encoding="utf-8", newline="") as f:  # newline="" 表头和数据之间不空行
            writer = csv.DictWriter(f, fieldnames=field_titles)
            writer.writeheader()
            for row_dict in values:
                writer.writerow(rowdict=row_dict)
        return True

    def write_iterative(self, values):
        """
        将可迭代格式的数据列表写入到csv文件
        :param values: 文件数据 示例:[("id", "name"), (1, "张三"), (2, "李四")]
        :return: True
        """
        with codecs.open(self.filename, "w", encoding="utf-8") as f:  # newline="" 表头和数据之间不空行
            writer = csv.writer(f)
            writer.writerows(values)
        return True

    def read_values(self, list=True, dict=False):
        """
        读取csv文件内的所有数据,可选返回列表格式和字典格式
        :param list: 返回数据为列表嵌套列表格式, 默认返回此类型
        :param dict: 返回数据为列表嵌套字典格式
        :return: 数据列表
        """
        values = []
        with open(self.filename, "r", encoding="utf-8") as f:
            if list:
                for value in csv.reader(f):
                    values.append(value)
            elif dict:
                # 以下两种方式读取都可以用 csv.reader(f), csv.DictReader(f)
                # for value in csv.reader(f):
                for value in csv.DictReader(f):
                    values.append(value)
        return values

    def read_list_values(self):
        """
        读取csv文件全部数据,返回列表嵌套格式的数据,同 read_values() 方法返回结果一致
        :return: 列表嵌套格式的数据
        """
        values = []
        with open(self.filename, "r", encoding="utf-8") as f:
            for value in csv.reader(f):
                values.append(value)
        return values



if __name__ == "__main__":
    c = Csv("./csv_tmp.csv")
    c.write_dict(field_titles=("id", "name"), values=[{"id": 1, "name": "a"}, {"id": 2, "name": "b"}, ])
    # c.write_iterative(values=[("id", "name"), (1, "张三"), (2, "李四")])
    print(c.read_values())
    print(c.read_list_values())

四、yaml 格式读写

输出结果:

import yaml
import os
import jsonpath



class YamlUtil:
    """
    yaml文件操作基础方法
    """
    def read_yaml(self, path):
        """
        从yaml文件内读取全部数据,文件内的key不能重复,否则读取最后一个
        :param path:
        :return:
        """
        with open(file=path, mode="r", encoding="utf-8") as f:
            yaml_data = yaml.load(f, Loader=yaml.BaseLoader)
            return yaml_data

    def read_yaml_by_key(self, path, key, index=0):
        """
        从 yaml 文件中读取指定 key 的数据 如果没有找到 jsonpath 方法会返回 False
        jsonpath http://goessner.net/articles/JsonPath
        :param path:
        :param key: 要查找的 key
        :param index: 找到符合条件数据列表的下标,默认为第一条数据
        :return: 对应 key 的值,没有找到返回 False
        """
        result = jsonpath.jsonpath(self.read_yaml(path), f"$..{key}")
        if not result:
            return result
        else:
            return result[index]

    def write_yaml(self, path, value):
        """
        往yaml文件内追加写入
        :param path:
        :param data:
        :return:
        """
        with open(file=path, mode="a", encoding="utf-8") as f:
            yaml.dump(data=value, stream=f, allow_unicode=True)

    def change_yaml_value(self, path, key, value):
        """
        修改yaml文件内某个具体key的value值。没有指定的key就追加。
        :param path:
        :param key: 需要修改的 key
        :param value: 需要修改的 key 的值
        :return:
        """
        yaml_data = self.read_yaml(path=path)
        if yaml_data:
            yaml_data[key] = value
        else:  # 文件内容为 None
            yaml_data = {key: value}
        # 先清除原有数据再把修改后的数据写入到文件
        self.clear_yaml(path=path)
        self.write_yaml(path=path, value=yaml_data)

    def clear_yaml(self, path):
        """
        清空yaml文件内容
        :param path:
        :return:
        """
        with open(file=path, mode="w", encoding="utf-8") as f:
            f.truncate()

    def yaml_full_file(self, loader, node):
        """ 构造器函数。需要配合 add_construct 方法一起使用。用来读取某个yaml文件内的全部内容 """
        # print(loader.name, node.value, node.tag)
        file_name = os.path.join(os.path.dirname(loader.name), node.value)  # 引用文件名
        return self.read_yaml(file_name)

    def yaml_value_by_key(self, loader, node, key):
        """ 构造器函数。需要配合 add_construct 方法一起使用。用来读取某个yaml文件内指定 key 的值 """
        file_name = os.path.join(os.path.dirname(loader.name), node.value)  # 引用文件名
        # return jsonpath.jsonpath(self.read_yaml(file_name), f"$..{key}")[0]
        return self.read_yaml_by_key(file_name, key)

    def add_construct(self, tag, func_name):
        """ 添加/注册自定义的构造器 """
        yaml.add_constructor(tag, func_name)


if __name__ == '__main__':
    # aaa = "./aaa.yml"
    # YamlUtil().clear_yaml(path=aaa)
    # YamlUtil().write_yaml(path=aaa, data={"desc": "娃哈哈"})
    # YamlUtil().write_yaml(path=aaa, data={"name": "张三"})
    # YamlUtil().write_yaml(path=aaa, data={"age": "10", "score": 99})
    # data = YamlUtil().read_yaml(path=aaa)
    # print(data)
    # YamlUtil().change_yaml_value(path=aaa, key="score", value=100)
    # YamlUtil().change_yaml_value(path=aaa, key="name", value="李四")
    # YamlUtil().change_yaml_value(path=aaa, key="desc", value="柴可夫斯基")
    # YamlUtil().change_yaml_value(path=aaa, key="class", value="小六")
    # data = YamlUtil().read_yaml(path=aaa)
    # print(data)
    pass

yaml 自定义构造器 在yaml文件内引用Python函数

import yaml
import time
import os
import jsonpath

"""
yaml 自定义构造器,可以在yaml文件中使用自定义构造器,然后调用外部文件或者Python方法
"""

def get_time():
    print(time.time())
    return time.time()


def yaml_full_file(loader, node):
    """ 构造器函数。用来读取某个yaml文件内的全部内容 """
    # print(loader.name, node.value, node.tag)
    file_name = os.path.join(os.path.dirname(loader.name), node.value)  # 引用文件名
    with open(file_name, encoding="utf-8") as f:
        return yaml.load(f, Loader=yaml.FullLoader)


def yaml_value_by_appversion(loader, node, key="appVersion", index=0):
    """ 构造器函数。用来读取某个yaml文件内指定 key 的值 """
    file_name = os.path.join(os.path.dirname(loader.name), node.value)  # 引用文件名
    with open(file_name, encoding="utf-8") as f:
        data = yaml.load(f, Loader=yaml.FullLoader)
        return jsonpath.jsonpath(data, f"$..{key}")[index]


def yaml_value_by_auth(loader, node, key="Authorization", index=0):
    """ 构造器函数。用来读取某个yaml文件内指定 key 的值 """
    file_name = os.path.join(os.path.dirname(loader.name), node.value)  # 引用文件名
    with open(file_name, encoding="utf-8") as f:
        data = yaml.load(f, Loader=yaml.FullLoader)
        return jsonpath.jsonpath(data, f"$..{key}")[index]


def yaml_value_by_host(loader, node, key="Host", index=0):
    """ 构造器函数。用来读取某个yaml文件内指定 key 的值 """
    file_name = os.path.join(os.path.dirname(loader.name), node.value)  # 引用文件名
    with open(file_name, encoding="utf-8") as f:
        data = yaml.load(f, Loader=yaml.FullLoader)
        return jsonpath.jsonpath(data, f"$..{key}")[index]


if __name__ == '__main__':
    # 添加自定义构造器
    yaml.add_constructor("!include", yaml_full_file)
    yaml.add_constructor("!appVersion", yaml_value_by_appversion)
    yaml.add_constructor("!auth", yaml_value_by_auth)
    yaml.add_constructor("!host", yaml_value_by_host)

    # 读取数据
    datas = yaml.load(stream=open("a.yml", mode="r", encoding="utf-8"), Loader=yaml.FullLoader)
    # print(datas['headers'])
    print(datas.get("headers"))
    print(datas.get("body_json"))
# a.yml

headers:
  User-Agent: "OkHttp Headers.java"
  Accept: "*/*"
  Accept-Encoding: ""
  Content-Type: "application/json; charset=utf-8"
  Authorization: !auth b.yml
  Host: !host b.yml
body_json:
  imei: ""
  appVersion: !appVersion b.yml
# b.yml

headers:
  Authorization: "aaaaaa_bbbbbbb"
  Host: "www.baidu.com"
body:
  appVersion: "1.0"
  userid: "100000"

五、其他

adb 手机设备信息读取

import subprocess
from icecream import ic


def read_usb_device_info():
    """
    获取当前usb链接的单一手机的设备号,安卓系统版本
    :return: {'deviceName': 'device id', 'platformVersion': 'android version'}
    """
    devicename_platformversion = {}

    def get_adb_result(command):
        """
        获取cmd命令行返回结果
        :param command: 命令行命令
        :return:
        """
        result = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE).stdout.read()
        return str(result).strip().replace("\\r", "").replace("\\n", "").replace("b", "").replace("'", "")
    try:
        # 获取设备id
        devices = get_adb_result("adb devices")
        # 获取安卓系统版本
        android_version = get_adb_result("adb shell getprop ro.build.version.release")
        # 获取干净的设备id
        devices = devices.split(" ")[-1].split("\\")[0].replace("attached", "")
        devicename_platformversion = {"deviceName": devices, "platformVersion": android_version}
    except Exception as e:
        devicename_platformversion = {}
    finally:
        ic(devicename_platformversion)
        return devicename_platformversion

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值