Python import模块的缓存问题解决方案


Posted in Python onJune 02, 2021

在使用django开发的平台中,支持用户自定义函数,但是每次用户进行修改编辑后,该模块内容已更改,然后重新导入该模块,但是Python 会认为“我已经导入了该模块,不需要再次读取该文件”,所以更改将无效。

因此,每次更改文件的内容时,都必须退出并重新启动Django。

使用python开发后台服务程序的时候,每次修改代码之后都需要重启服务才能生效比较麻烦

要解决这个问题,有以下几种方式:

最简单、最有效的方法:重新启动 Django。但是,这也有缺点,特别是丢失了 django名称空间中存在的数据以及其他导入模块中的数据。

对于简单的情况,可以使用 Python 的​reload()​函数。在许多情况下,在编辑一个模块之后使用

​reload()​函数就足够满足需求。

这里主要是介绍第二种方式:

​reload()​是 Python 提供的内置函数,在不同的 Python 版本中有不同的表现形式:

在 Python 2.x 中,reload()是内置函数。

在 Python 3.0 - 3.3 中,可以使用imp.reload(module)

在 Python 3.4 中,imp 已经被废弃,取而代之的是importlib

Python2.7可以直接用reload():

python2 内置函数reload(module)

Python3可以用下面几种方法:

方法一:基本方法

from imp import reload
reload(module)

方法二:

import imp
imp.reload(module)

方法三:

import importlib
importlib.reload(module)

方法四:

from importlib import reload
reload(module)

说明:

module 必须是已经成功导入的模块

模块被加载到内存以后,更改文件内容,已经运行的程序不会生效的,可通过reload重新加载。

导入是一个开销很大的操作。

python中缓存模块的一些用法

一.问题描述

有时候可能需要缓存一些 成员方法的值, 可能成员方法的计算比较耗时,有时候不希望重复调用计算该值, 这个时候就可以缓存该值.

查了一下标准库 有 functools.lru_cache 有一个 lru_cache 可以缓存成员函数的值,

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@author: Frank 
@contact: frank.chang@shoufuyou.com
@file: test_lru_cache.py
@time: 2018/9/8 下午8:55
"""
import time
from functools import lru_cache

class Model:
    @lru_cache(maxsize=10)
    def calculate(self, number):
        print(f'calculate({number}) is  running,', end=' ')
        print('sleep  3s  ')
        time.sleep(3)
        return number * 3

if __name__ == '__main__':

    model = Model()

    for i in range(5):
        print(model.calculate(i))

    for i in range(5):
        print(model.calculate(i))

结果如下:

calculate(0) is  running, sleep  3s 
0
calculate(1) is  running, sleep  3s 
3
calculate(2) is  running, sleep  3s 
6
calculate(3) is  running, sleep  3s 
9
calculate(4) is  running, sleep  3s 
12
0
3
6
9
12

从结果开出来, 第二次计算的时候 , 就没有计算 而是通过缓存取值, 所以成员方法只计算了一次.

lru_cache 可以指定 max_size 缓存的大小, typed bool 如果为True, 代表不同类型分别缓存. 如果达到max_size 淘汰策略是LRU, LRU是Least Recently Used的缩写,即最近最少使用,常用于页面置换算法.

二 第三方的模块

第三方的模块cachetools 已经提供了很多缓存策略,直接拿来用一下.

来看下面的例子.

1 来看一个缓存成员方法例子

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@author: Frank 
@contact: frank.chang@shoufuyou.com
@file: test_cache.py
@time: 2018/9/8 下午12:59
pip install cachetools

https://docs.python.org/3/library/operator.html

缓存成员方法的值 
cachetools  已经实现好了, 直接用就可以了. 

"""
from operator import attrgetter
import time
from cachetools import LRUCache,RRCache , cachedmethod

class Model:
    def __init__(self, cachesize):
        self.cache = LRUCache(maxsize=cachesize)

    @cachedmethod(attrgetter('cache'))
    def get_double_num(self, num):
        """ return  2* num"""
        print(f'get_double_num({num})  is running')
        time.sleep(2)
        return num * 2

model = Model(cachesize=10)
print(model.get_double_num(10))
print(model.get_double_num(10))
print(model.get_double_num(10))
print(model.get_double_num(10))
print(model.get_double_num(10))
print(model.get_double_num(10))

结果如下:

get_double_num(10)  is running
20
20
20
20
20
20
Process finished with exit code 0

可以看出, 值计算一次 函数,第二次走的是缓存. 非常好用. 在初始化方法里面构造一个缓存对象, 之后用 cachedmethod 修饰成员函数,同时 用attrgetter(‘cache') 把cache 拿到就可以用了.

实际上 cachetools 实现了很多缓存策略,具体缓存策略可以参考下面的链接.

'Cache', 'LFUCache',
'LRUCache',
'RRCache', 'TTLCache',

‘cached', ‘cachedmethod' 这两个分别用来修饰 函数和成员方法的.

2 来看一个 缓存函数

# 缓存 函数的值
from cachetools import cached
@cached(cache={})
def fib(n):
    print((f'fib({n}) is  running.'))
    return n if n < 2 else fib(n - 1) + fib(n - 2)

for i in range(20):
    print('fib(%d) = %d' % (i, fib(i)))
@cached(cache={})
def fun(n):
    print(f'fun({n}) is runnnig.')
    time.sleep(3)
    return n ** 2

if __name__ == '__main__':
    for _ in range(5):
        print(fun(4))

如果cache = None , 表示不缓存,该计算结果.

结果如下:

fun(4) is runnnig.
16
16
16
16
16

直接导入 cached 里面 传入一个字典就可以了,用起来也比较方便.

实现分析:

缓存思路大致是一样的, 首先先把参数hash 一下生成一个key, 然后看key 是否在自己的缓存里,不在就计算方法(函数),之后把key和对应value 放到自己的子弟那里面. 如果下一次计算该值,生成一个key 看是否在 自己的字典里面,如果在直接返回即可. 当然这是基本的思路, 里面还有用到 缓存淘汰策略, 多线程是否要加锁,等比较复杂的问题.

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python高级应用实例对比:高效计算大文件中的最长行的长度
Jun 08 Python
Python中内置的日志模块logging用法详解
Jul 12 Python
django静态文件加载的方法
May 20 Python
Python对数据进行插值和下采样的方法
Jul 03 Python
python正则表达式匹配[]中间为任意字符的实例
Dec 25 Python
Python数据可视化:幂律分布实例详解
Dec 07 Python
python给视频添加背景音乐并改变音量的具体方法
Jul 19 Python
python3排序的实例方法
Oct 20 Python
使用python将微信image下.dat文件解密为.png的方法
Nov 30 Python
selenium3.0+python之环境搭建的方法步骤
Feb 01 Python
深度学习详解之初试机器学习
Apr 14 Python
python 字典和列表嵌套用法详解
Jun 29 Python
Python3 类型标注支持操作
Jun 02 #Python
python 实现两个变量值进行交换的n种操作
聊聊Python中关于a=[[]]*3的反思
python内置进制转换函数的操作
Jun 02 #Python
Python 内置函数速查表一览
Jun 02 #Python
利用Python判断你的密码难度等级
Jun 02 #Python
Python标准库之typing的用法(类型标注)
You might like
Yii结合CKEditor实现图片上传功能
2014/06/13 PHP
php中隐形字符65279(utf-8的BOM头)问题
2014/08/16 PHP
解决form中action属性后面?传递参数 获取不到的问题
2017/07/21 PHP
PHP流Streams、包装器wrapper概念与用法实例详解
2017/11/17 PHP
php 替换文章中的图片路径,下载图片到本地服务器的方法
2018/02/06 PHP
js 效率组装字符串 StringBuffer
2009/12/23 Javascript
使用jQuery validate 验证注册表单实例演示
2013/03/25 Javascript
js将json格式内容转换成对象的方法
2013/11/01 Javascript
js事件监听器用法实例详解
2015/06/01 Javascript
js+flash实现的5图变换效果广告代码(附演示与demo源码下载)
2016/04/01 Javascript
node.js cookie-parser之parser.js
2016/06/06 Javascript
Bootstrap实现翻页效果
2017/11/27 Javascript
基于jQuery实现Ajax验证用户名是否可用实例
2018/03/25 jQuery
webpack实现一个行内样式px转vw的loader示例
2018/09/13 Javascript
利用Vue的v-for和v-bind实现列表颜色切换
2020/07/17 Javascript
使用webpack和rollup打包组件库的方法
2021/02/25 Javascript
[03:17]2014DOTA2 国际邀请赛中国区预选赛 四强专访
2014/05/23 DOTA
[02:52]2014DOTA2西雅图国际邀请赛 CIS战队巡礼
2014/07/07 DOTA
Python3中简单的文件操作及两个简单小实例分享
2017/06/18 Python
Python多图片合并PDF的方法
2019/01/03 Python
python使用PyQt5的简单方法
2019/02/27 Python
浅析PyTorch中nn.Module的使用
2019/08/18 Python
Python单元测试模块doctest的具体使用
2020/02/10 Python
高考考python编程是真的吗
2020/07/20 Python
一文详述 Python 中的 property 语法
2020/09/01 Python
python statsmodel的使用
2020/12/21 Python
CSS3中几个新增加的盒模型属性使用教程
2016/03/01 HTML / CSS
StudentUniverse英国:学生航班、酒店和旅游
2019/08/25 全球购物
三星法国官方网站:Samsung法国
2019/10/31 全球购物
Crabtree & Evelyn欧盟:豪华洗浴、身体和护发
2021/03/09 全球购物
开办化妆品公司创业计划书
2013/12/26 职场文书
高中生职业生涯规划书
2014/02/24 职场文书
货物运输服务质量承诺书
2014/05/29 职场文书
汽车修理厂管理制度
2015/08/05 职场文书
python爬虫之selenium库的安装及使用教程
2021/05/23 Python
Spring mvc是如何实现与数据库的前后端的连接操作的?
2021/06/30 Java/Android