Python日常记录

1)获取文件名

os.path.splitext函数来一次性获取文件名和扩展名,然后检查扩展名是否为.xlsx。如果不是,我们只需添加正确的扩展名即可。

import os

excel_file = "example.xls"  # 假设这是你的输入文件名
base_name, ext = os.path.splitext(excel_file)
if ext.lower() != '.xlsx':
    excel_file = base_name + '.xlsx'


# 输出文件
tmp = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d-%H')
file_out = f'1.{tmp}-{table_name}-共计{len1}张.xlsx'  # 输出文件名称

excel_file = os.path.splitext(excel_file)[0] + ".xlsx"




def query_data_and_save_to_excel(database, table, excel_file):
    with db_lock:
        try:
            # 连接SQLite数据库
            conn = sqlite3.connect(database)
            # 查询数据库表数据
            query = f"SELECT * FROM {table}"
            df = pd.read_sql_query(query, conn)
            excel_file = os.path.splitext(excel_file)[0] + ".xlsx"
            df.to_excel(excel_file, index=False)
            print("数据成功保存 {}".format(excel_file))
        except Exception as e:
            logger.error(f"发生错误: {e}")
        finally:
            # 关闭数据库连接
            if conn:
                conn.close()

2)DB_SQLITE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'db.sqlite3')

DB_SQLITE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'db.sqlite3') 这行代码的作用是构建一个指向当前脚本所在目录下名为 db.sqlite3 的文件的绝对路径。具体来说,它使用了Python的os模块中的一些函数来实现这个功能。

  • os.path.abspath(__file__):获取当前脚本文件的绝对路径。

  • os.path.dirname():获取给定路径的目录名。在这里,它获取了当前脚本文件所在的目录。

  • os.path.join():将两个路径组合成一个路径。在这里,它将目录名和文件名('db.sqlite3')组合在一起,形成一个完整的文件路径。

3)装饰器@retry  发送GET请求

定义了一个名为send_get_request的函数,用于发送GET请求并返回响应。函数使用了装饰器@retry,该装饰器会在发生异常时自动重试指定次数(本例中为2次),并在每次重试之间等待指定的延迟时间(本例中为1秒)。

具体来说,函数的功能如下:

  • 创建一个requests.Session()对象,用于管理HTTP请求和响应。
  • 使用session.get()方法发送GET请求,传入URL、请求头、查询参数和超时时间。
  • 如果请求成功且状态码为200,则返回响应对象。
  • 如果请求过程中发生异常(如网络错误、超时等),则记录错误日志并抛出异常。
@retry(tries=2, delay=1)
def send_get_request(url, headers=None, params=None, timeout=20):
    session = requests.Session()
    try:
        response = session.get(url, headers=headers, params=params, timeout=timeout)
        response.raise_for_status()
        return response
    except Exception as e:
        logger.error(f"请求发生异常: {e} - {url}")
        raise

4)发送POST请求

使用requests库的Session对象来复用TCP连接,从而提高性能。

# 定义一个装饰器函数,用于处理重试逻辑
@retry(tries=2, delay=1)
def get_token_with_retry(session, url, data, headers):
    response = session.post(url, data=json.dumps(data), headers=headers)
    response.raise_for_status()  # 检查请求是否成功
    return response.text

def get_token(operator, data):
    url = "https://Token"
    headers = {'Content-Type': 'application/json', 'Accept-Encoding': 'gzip, deflate, br'}
    session = requests.Session()
    try:
        token = get_token_with_retry(session, url, data, headers)
        if token:
            update_tokenini_data(operator, 'TOKEN', f"{token}")
            logger.info(f'时间:{datetime.datetime.now()}-->{operator}-{token} 更新成功')
            return token
    except (requests.exceptions.RequestException, ValueError) as e:
        logger.error(f"TOKEN请求异常:{e}")
        return None

5)raise关键字

用于抛出异常。当程序遇到错误或异常情况时,可以使用raise语句手动触发异常。raise后面通常跟着一个异常类或异常实例,表示要抛出的异常类型。如果不指定异常类型,将默认抛出RuntimeError异常。

def divide(a, b):
    if b == 0:
        raise ValueError("除数不能为0")
    return a / b

try:
    result = divide(10, 0)
except ValueError as e:
    print(e)


我们定义了一个divide函数,用于计算两个数相除的结果。如果除数为0,我们使用raise抛出一个ValueError异常,并附带一条错误信息。在调用divide函数时,我们使用try-except语句捕获异常,并在发生异常时打印错误信息。

注意事项
raise语句只能在函数或方法内部使用,不能在全局作用域或类定义中使用。
如果没有捕获到异常,程序将终止执行,并显示异常信息。
可以自定义异常类,继承自内置的异常类(如Exception),以创建更具体的异常类型。

6)logger日志管理

from loguru import logger
logger.add(
    sink="./logs/appAPN.log",
    enqueue=True,
    rotation="2 MB",
    retention="4 months",
    encoding="utf-8",
    backtrace=True,
    diagnose=True,
    #compression="zip",
)

logger.add() 是 Python 中的一个方法,用于向日志记录器添加一个日志处理器。这个方法接收多个参数,用于配置日志处理器的行为。以下是各个参数的解释:

  • sink: 指定日志文件的路径。在这个例子中,日志将被写入到 "./logs/appAPN.log" 文件中。
  • enqueue: 如果设置为 True,则日志记录将被异步地添加到队列中,而不是直接写入文件。这可以提高性能,特别是在多线程或多进程环境中。
  • rotation: 设置日志文件的最大大小。在这个例子中,当日志文件达到 2 MB 时,将创建一个新的日志文件。旧的日志文件将被保留,直到达到指定的保留时间。
  • retention: 设置日志文件的保留时间。在这个例子中,日志文件将被保留 4 个月。超过这个时间的日志文件将被删除。
  • encoding: 设置日志文件的编码格式。在这个例子中,使用 utf-8 编码。
  • backtrace: 如果设置为 True,则在捕获异常时,将记录完整的堆栈跟踪信息。
  • diagnose: 如果设置为 True,则在捕获异常时,将记录诊断信息,如异常类型和异常值。
  • compression: 可选参数,用于指定日志文件的压缩格式。在这个例子中,注释掉了这个参数,所以不会对日志文件进行压缩。

7)使用str.strip()方法去除两侧的空格

lambda表达式中,我们检查每个元素的数据类型是否为字符串(即object),如果是,则使用str.strip()方法去除两侧的空格;如果不是,则保持原样。

    # 读取Excel数据
    df = pd.read_excel(file_path,dtype=str)

    # 去除所有数据中的空格
    df = df.apply(lambda x: x.str.strip() if x.dtype == "object" else x)

8)设置pip源及pyqt安装

pip config list -v
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

C:\Users\XX\AppData\Roaming\pip\pip.ini




pip install pyqt5 -i https://mirrors.aliuyun.com/pypi/simple
pip install pyqt5 pyqt5-tools -i https://mirrors.aliuyun.com/pypi/simple

pyqt5 pyqt5-tools:高版本python安装不上,可以直接安装pyqt5designer配合vscode使用
pip install pyqt5designer 


9)pandas导出转换成数值类型

解析:

  1. df[['月用量GB', '月用量MB', '月用量KB']]:选择DataFrame df中的'月用量GB'、'月用量MB'和'月用量KB'这三列。
  2. apply(pd.to_numeric, errors='coerce'):对选定的列应用pd.to_numeric函数,将其转换为数值类型。如果某个值无法转换为数值,则将其设置为NaN。
  3. fillna('--'):将NaN值替换为字符串'--'。


def query_data_and_save_to_excel(database, table, excel_file):
    with db_lock:
        try:
            # 连接SQLite数据库
            conn = sqlite3.connect(database)
            # 查询数据库表数据
            query = f"SELECT * FROM {table}"
            df = pd.read_sql_query(query, conn)
            excel_file = os.path.splitext(excel_file)[0] + ".xlsx"
            # 将age列的数据类型转换为字符串
            df[['月用量GB', '月用量MB', '月用量KB']] = df[['月用量GB', '月用量MB', '月用量KB']].apply(pd.to_numeric, errors='coerce').fillna('--')
            df.to_excel(excel_file, index=False)
            print("数据成功保存 {}".format(excel_file))
        except Exception as e:
            logger.error(f"发生错误: {e}")
        finally:
            # 关闭数据库连接
            if conn:
                conn.close()

10)文件互斥锁


import threading

class FileReaderWriter:
    def __init__(self, file_path):
        self.file_path = file_path
        self.mutex = threading.Lock()

    def read_file(self):
        with self.mutex:
            with open(self.file_path, 'r') as file:
                content = file.read()
                print("读取文件内容:", content)

    def write_file(self, content):
        with self.mutex:
            with open(self.file_path, 'w') as file:
                file.write(content)
                print("写入文件内容:", content)

# 示例用法
file_reader_writer = FileReaderWriter('example.txt')

def read_file():
    file_reader_writer.read_file()

def write_file():
    file_reader_writer.write_file('Hello, World!')

# 创建多个线程进行读写操作
threads = []
for i in range(5):
    threads.append(threading.Thread(target=read_file))
    threads.append(threading.Thread(target=write_file))

for t in threads:
    t.start()

for t in threads:
    t.join()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值