常用工具集

此blog主要记录下平常工作中遇到需求而写的工具,以便后面遇到可以方便取用

一、最近在改django框架,经常出来不知道哪冒出来的打印,就查了下gpt能够打印print所在文件等的方法,在这里记录一下

# print info tool
import inspect


def print_with_info(*args, **kwargs):
    frame = inspect.currentframe().f_back
    file_name = frame.f_code.co_filename
    line_no = frame.f_lineno
    func_name = frame.f_code.co_name
    class_name = frame.f_locals.get('self', None).__class__.__name__
    info = f"{file_name}:{line_no}|{class_name}.{func_name}>>>>"
    print(info, *args, **kwargs)

上述代码可以打印出代码打印所在文件,行数,类名,函数名等,在所需文件导入后正常像print一样使用即可

二、客户有时需要无侵入的满足一些需求,使用mock方式给代码打补丁,替换其中使用的部分方法

可以使用 Python 中的 mock 模块来实现在不修改导入的包的前提下,将导入的包的函数变为自己开发的函数。具体步骤如下:

导入需要使用的模块和函数,例如:

`python
Copy code`

import requests
from requests.exceptions import HTTPError


使用 mock 模块来替换需要修改的函数,例如:

`python
Copy code`

from unittest.mock import patch
def my_mock_function(*args, **kwargs):
    # 自定义的函数实现
    pass
with patch.object(requests, 'get', side_effect=my_mock_function):
    # 在此处调用 requests.get() 函数的代码将使用 my_mock_function() 进行替代
    # 例如:
    try:
        response = requests.get('https://www.example.com')
        response.raise_for_status()
    except HTTPError as http_err:
        print(f'HTTP error occurred: {http_err}')
    except Exception as err:
        print(f'Other error occurred: {err}')

在以上示例中,我们使用了 patch.object() 方法来替换 requests 模块中的 get() 函数,并将其替换为自定义的 my_mock_function() 函数。在使用 requests.get() 函数的代码块中,实际调用的函数将被替换为 my_mock_function()。
需要注意的是,以上示例仅是一个简单的示例,实际情况可能更为复杂,需要考虑到具体的应用场景和需求,以及所使用的模块和函数的实现细节。因此,在实际使用中,建议先详细了解 Python 的 mock 模块和被替换的函数的实现,再进行相关的编写和配置工作。

三、在改django源码时,要将request对象在其他模块获取到,因为要做到无侵入,所以要基本无感,先将wsgi request存放到线程中

使用线程存储wsgi对象,不过需要在django中加个中间件

使用 threadlocals Django 提供了一个 threadlocals 模块,可以在当前线程中存储一些全局变量,这些变量对整个线程都是可见的。可以将 request 对象存储在 threadlocals 中,然后在第三方包中获取。 在 Django 中: (这里我还提取了django配置文件因为项目需要)

import threading
from django.conf import settings
import socket
_thread_locals = threading.local()


class ThreadLocalsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        _thread_locals.request = request
        response = self.get_response(request)
        return response

    @staticmethod
    def get_current_request():
        return getattr(_thread_locals, 'request', None)

    @staticmethod
    def get_settings():
        return settings

在上面的代码中,我们定义了一个 get_current_request 函数,它会返回当前线程的 request 对象。最后,我们创建了一个中间件 ThreadLocalsMiddleware。 在第三方包中,可以通过调用 get_current_request() 函数来获取当前请求的 request 对象。

需要注意的是,使用 threadlocals 存储 request 对象的方式,需要在每个请求之前都调用中间件 ThreadLocalsMiddleware,否则 threadlocals 中将没有 request 对象,获取 request 对象时会返回 None。

posted @ 2023-03-30 10:52  seas  阅读(33)  评论(0编辑  收藏  举报