├── MANIFEST.in ├── m.py ├── test.py ├── README.md ├── setup.py ├── LICENSE.txt └── pyautoreload └── __init__.py /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.md 2 | -------------------------------------------------------------------------------- /m.py: -------------------------------------------------------------------------------- 1 | def test(): 2 | print 11 3 | print 123 4 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | 3 | import time 4 | 5 | import m 6 | import pyautoreload 7 | 8 | if __name__ == '__main__': 9 | while True: 10 | pyautoreload.reload_module(m) 11 | m.test() 12 | time.sleep(1) 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pyautoreload 2 | 一个可以动态加载重载的模块,可以是对象或者是模块的字符串形式. 3 | 4 | TO DO List: 5 | 6 | 1. 加入目录监控 7 | 8 | 2. 加入inotify被动扫描 9 | 10 | 3. 加入信号模式 11 | 12 | ###安装: 13 | 14 | pypi安装 15 | ``` 16 | pip install pyautoreload 17 | ``` 18 | 源码安装 19 | ``` 20 | git clone https://github.com/rfyiamcool/pyautoreload.git 21 | cd pyautoreload 22 | python setup.py install 23 | ``` 24 | 25 | 26 | ###使用方法: 27 | 28 | * 重新加载指定模块 29 | 30 | pyautoreload.reload_module(m) 31 | 32 | * 加入模块 33 | 34 | pyautoreload.import_str('a.b.c.d') 35 | 36 | 路径: /a/b/c 37 | 38 | 函数: d 39 | 40 | * 删除模块 41 | 42 | delete_str(m) 43 | 44 | * 重新加载所有模块 45 | 46 | reload_all() 47 | 48 | * 重新加载模块,支持类及函数路径模式 49 | 50 | reload_str() 51 | 52 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | from setuptools import setup, find_packages 3 | 4 | def read(fname): 5 | return open(os.path.join(os.path.dirname(__file__), fname)).read() 6 | 7 | setup( 8 | name = "pyautoreload", 9 | version = "1.3", 10 | author = "ruifengyun", 11 | author_email = "rfyiamcool@163.com", 12 | description = "dynamic reload module", 13 | license = "MIT", 14 | keywords = ["dynamic reload module","fengyun"], 15 | url = "https://github.com/rfyiamcool", 16 | long_description = read('README.md'), 17 | packages=['pyautoreload'], 18 | install_requires=['pyinotify'], 19 | classifiers = [ 20 | 'Development Status :: 2 - Pre-Alpha', 21 | 'Intended Audience :: Developers', 22 | 'License :: OSI Approved :: MIT License', 23 | 'Programming Language :: Python :: 2.7', 24 | 'Programming Language :: Python :: 3.0', 25 | 'Topic :: Software Development :: Libraries :: Python Modules', 26 | ] 27 | ) 28 | 29 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 fengyun rui 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /pyautoreload/__init__.py: -------------------------------------------------------------------------------- 1 | #coding:utf--8 2 | import imp 3 | import sys 4 | import types 5 | import importlib 6 | 7 | #内建函数 8 | _is_builtin = imp.is_builtin 9 | 10 | #重载 11 | _reload = reload 12 | 13 | #to do 14 | def watch(addr): 15 | pass 16 | 17 | def import_str(objpath): 18 | objlist = objpath.split('.') 19 | func = objlist[-1] 20 | module_path = objlist[:-1] 21 | obj = __import__(module_path,globals(),locals(),[func]) 22 | return getattr(obj,func) 23 | 24 | def delete_module(obj): 25 | if isinstance(obj,types.ModuleType): 26 | del obj 27 | return True 28 | return False 29 | 30 | def delete_str(objpath): 31 | objlist = objpath.split('.') 32 | func = objlist[-1] 33 | module_path = objlist[:-1] 34 | del sys.modules[module_path] 35 | 36 | def reload_str(obj): 37 | delete_str(obj) 38 | import_str(obj) 39 | 40 | def _get_dependencies(module): 41 | for variable in vars(module).values(): 42 | if not isinstance(variable, types.ModuleType): 43 | continue 44 | if _is_builtin(variable.__name__): 45 | continue 46 | yield variable 47 | 48 | def _get_modules_in_order(module, done=set()): 49 | done = {module.__name__} 50 | for dependency in _get_dependencies(module): 51 | if dependency.__name__ not in done: 52 | for subdependency in _get_modules_in_order(dependency, done): 53 | yield subdependency 54 | yield module 55 | 56 | def reload_module(module): 57 | for module in _get_modules_in_order(module): 58 | if module.__name__ in sys.modules: 59 | try: 60 | sys.modules[module.__name__] = _reload(module) 61 | except ImportError: 62 | continue 63 | 64 | def reload_all(): 65 | """ 66 | 重新加载所有模块 67 | """ 68 | for name, module in sys.modules.items(): 69 | if module and name != '__main__': 70 | reload_module(module) 71 | --------------------------------------------------------------------------------