在使用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可以用下面几种方法:
方法一:基本方法
1
2
|
reload (module) |
方法二:
1
2
|
import imp imp. reload (module) |
方法三:
1
2
|
import importlib importlib. reload (module) |
方法四:
1
2
|
from importlib import reload reload (module) |
说明:
module 必须是已经成功导入的模块
模块被加载到内存以后,更改文件内容,已经运行的程序不会生效的,可通过reload重新加载。
导入是一个开销很大的操作。
python中缓存模块的一些用法
一.问题描述
有时候可能需要缓存一些 成员方法的值, 可能成员方法的计算比较耗时,有时候不希望重复调用计算该值, 这个时候就可以缓存该值.
查了一下标准库 有 functools.lru_cache 有一个 lru_cache 可以缓存成员函数的值,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#!/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 来看一个缓存成员方法例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
#!/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 实现了很多缓存策略,具体缓存策略可以参考下面的链接.
1
2
3
|
'Cache' , 'LFUCache' , 'LRUCache' , 'RRCache' , 'TTLCache' , |
‘cached', ‘cachedmethod' 这两个分别用来修饰 函数和成员方法的.
2 来看一个 缓存函数
1
2
3
4
5
6
7
8
9
|
# 缓存 函数的值 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))) |
1
2
3
4
5
6
7
8
9
|
@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 看是否在 自己的字典里面,如果在直接返回即可. 当然这是基本的思路, 里面还有用到 缓存淘汰策略, 多线程是否要加锁,等比较复杂的问题.
以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/qq_23948283/article/details/108063056