常用模块封装-dubbo、excel、日志、requests请求、文件操作

1.dobbo操作

封装模块:Telnetlib的telnet类是一个关于telnet协议的类。

telnet协议:是一个远程终端协议,tcp/ip协议的一员,属于应用层。

                    作用:可以在本地计算机,通过网络进入另一个电脑。

交互过程:使用telnet进入远程算计系统,启动2个程序:本地主机:telnet客户端程序;远程主机:telnet服务器程序

python实现telnet客户端主要功能:(1)连接主机(2)执行命令

封装思路:
1.创建telnet对象,连接主机
2.执行命令
3.退出机器,关闭连接

使用场景:
执行dubbo命令

class Dubbo:
    def __init__(self, connections: tuple):
        """
        连接主机
        :param connections: host, port
        """
        self.tn = telnetlib.Telnet(*connections)

    def __del__(self):
        # 退出机器
        self.tn.write(b'quit\n')
        # 关闭连接
        self.tn.close()

    def do(self, command_str):
        # 执行命令
        print(datetime.now().strftime('%Y-%m-%d %H:%M:%S %f')[:-3])
        print('【执行命令】:', command_str)
        self.tn.write(command_str.encode() + b'\n')

        # 在IO不阻塞的情况下读取所有的数据,否则返回空
        time.sleep(2)
        data = self.tn.read_very_eager()
        # 解码返回的数据
        print('返回结果:', data.decode())
        return data.decode()

2.excel

import openpyxl


def excel_handler(filename, sheetname):
    """
    处理excel数据
    :param filename: excel路径
    :param sheetname: excel sheetname
    :return:
    """
    # 打开excel
    wb = openpyxl.load_workbook(filename)
    # sheet
    ws = wb.active
    if sheetname:
        ws = wb[sheetname]

    row_list = list(ws.rows)

    # 表头
    headers = [row.value for row in row_list[0]]
    # 生成[{},{}]形式
    case_list = []
    for row in row_list[1:]:
        case_list.append(dict(zip(headers, [cell.value for cell in row])))
    return case_list

3.日志

import logging
import colorlog
from logging.handlers import TimedRotatingFileHandler


def get_logger(name, filename, when='s', interval=1, backupCount=1, encoding='utf-8', debug=True, fmt=None):
    """
    打印日志
    :param name: 日志器名称
    :param filename: 日志保存文件名
    :param when: 时间单位
    :param interval: 间隔时间
    :param backupCount: 循环
    :param encoding:
    :param debug:
    :param fmt:
    :return:
    """
    # 1创建日志器
    logger = logging.getLogger(name)
    logger.setLevel(logging.DEBUG)

    # 处理参数
    if debug:
        file_level = logging.DEBUG
        console_level = logging.DEBUG
    else:
        file_level = logging.WARN
        console_level = logging.INFO

    if fmt is None:
        fmt = '%(levelname)s %(asctime)s [%(filename)s-->line:%(lineno)d]:%(message)s'

    # 2.创建日志处理器
    file_handle = TimedRotatingFileHandler(filename, when=when, interval=interval, backupCount=backupCount, encoding=encoding)
    file_handle.setLevel(file_level)

    console_handle = logging.StreamHandler()
    console_handle.setLevel(console_level)

    # 3. 创建格式化器
    # 文件格式化器
    file_formatter = logging.Formatter(fmt=fmt)

    # 控制台的格式化器
    log_colors_config = {
        'DEBUG': 'white',  # cyan white
        'INFO': 'cyan',
        'WARNING': 'green',
        'ERROR': 'bold_red',
    }
    console_formatter = colorlog.ColoredFormatter(
        fmt='%(log_color)s'+fmt,
        log_colors=log_colors_config)

    # 4.添加格式化器
    file_handle.setFormatter(file_formatter)
    console_handle.setFormatter(console_formatter)

    # 5.添加日志处理器
    logger.addHandler(file_handle)
    logger.addHandler(console_handle)
    return logger

4.requests请求

def req(url, headers, method='post', if_print=True, **kargs):
    """
    发请求:如果出现异常会循环请求|响应为403,会循环请求3次
    :param url:
    :param headers:
    :param method:
    :param res_type: 响应类型
    :param kargs: 请求其他参数:dict
    :return:
    """
    i = 0
    while i < 3:
        try:
            logger.debug('============URL============')
            logger.debug(url)
            logger.debug('============method============\n{}'.format(method))
            logger.debug('============headers============\n{}'.format(headers))
            if if_print is True:
                for key, value in kargs.items():
                    logger.debug('============{}============\n{}'.format(key.lower(), value))
            logger.debug('============请求时间============\n{}'.format(time.strftime('%Y-%m-%d %H:%M:%S')))
            res = getattr(requests, method)(url=url, headers=headers, **kargs)
            logger.debug('============响应状态码============\n{}'.format(res.status_code))
            logger.debug('============响应结果============\n{}'.format(res.text))

            if res.status_code == 403:
                logger.info('响应状态码为403')
                i += 1
                continue
        except requests.exceptions.RequestException as e:
            logger.error(e)
            logger.info('错误次数:{}'.format(i))
            i += 1
        else:
            return res

5.文件操作

import copy
import os


class FileOperation:
    def write_file(self, file_path, content):
        """写文件"""
        with open(file_path, 'wb') as file:
            file.write(content)

    def read_file(self, file_path):
        """读取文件"""
        with open(file_path, 'rb') as file:
            content = file.read()
            return content

    def copy_file(self, file_path):
        """复制文件"""
        copy_file = copy.deepcopy(self.read_file(file_path))
        return copy_file

    def get_file_path(self, file_name, if_material_path=True):
        """获取文件路径"""
        parent_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        material_path = 'file/material_file' if if_material_path is True else 'file/tempory_file'
        return os.path.join(parent_path, material_path, file_name)

6.subprocess封装

subprocess模块:类似系统的cmd,执行系统命令,启动进程,并且连接到他们的输入输出管道,从而获取返回值

subprocess的Popen类:创建一个进程,传入的命令类型:str/list,

eg:adb devices/[adb,devices]。但是前者如果shell=False,不会工作;如果是True,则相当于subprocess.Popen(["/bin/sh", "-c", "cat test.txt"]),会正常处理

Popen.communicate():和进程交互,发送命令,从stdout和stderr读取数据并返回

如果需要传入的命令,命令类型:byte or string。

封装思路:

1.执行命令,创建子进程

2.和进程交互,(执行命令,可选),获取返回stdout和stder

3.执行完命令结束进程

import subprocess


def execute_shell_str(cmd):
    """启动进程,执行命令
    cmd:str/list: adb devices/[adb,devices],适用于单个命令
    """
    print(cmd)
    # 创建子进程
    # Popen()类中,cmd:字符串或者列表 "cat test.txt" 或者 ["cat","test.txt"],
    # 但是前者如果shell=False,不会工作;如果是True,则相当于subprocess.Popen(["/bin/sh", "-c", "cat test.txt"]),会正常处理
    obj = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE, shell=True)   # A string
    try:
        # 与进程交互
        stdout, stderr = obj.communicate()
        print("当前执行进程号为:{}".format(obj.pid))
        print('===stdout===', stdout.decode('gbk'), stderr.decode('gbk'))
        return stdout.decode()
    except Exception as e:
        raise e
    finally:
        # 结束进程号
        obj.kill()
        print(f"当前返回状态:{obj.poll()}")  # 0:正常结束;1:异常


def execute_shell(cmd):
    """启动进程,执行完整的命令,适用于多条命令
    cmd:str/list
    eg:
    cmd="adb devices"
    cmd = [
        "adb devices",
        "where adb"  # 这是是非常关键的,退出
    ]
    """
    print(cmd)
    cmd = [cmd] if type(cmd) is str else cmd
    for i in cmd:
        print('cmd===', i)
        obj = subprocess.Popen(i, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE, shell=True)  # i:A string
        stdout, stderr = obj.communicate()
        print(stdout.decode(), stderr.decode('gbk'))
        # 结束进程号
        obj.kill()
        print(f"当前返回状态:{obj.poll()}\n")  # 0:正常结束;1:异常


def adb_shell(cmds):
    """
    进入某个环境执行语句(adb shell),命令用列表方式全部列出,,适用于执行adb shell命令
    注意:1.shell内部命令需要带\n,执行完后一定记得执行exit命令退出,否则会阻塞
         2.有些路径下执行命令需要有root权限
    cmds = [
    "cd data",
    'cd data',
    "ls",
    "exit",#这是是非常关键的,退出
]
    """
    print(cmds)
    # 进入某个环境(adb shell)
    obj = subprocess.Popen("adb shell", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)  # A string, or a sequence of program arguments.
    # 在adb shell环境下执行命令
    stdout, stderr = obj.communicate(("\n".join(cmds) + "\n").encode())  # byte or string; Send data to stdin
    print(stdout.decode('gbk'), stderr.decode('gbk'))
    return stdout.decode('gbk')

 tips:在windows执行adb shell命令查看目录下文件:ll;但是使用python调用adb命令需要用ls

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值