module-bank 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,11 @@
1
+ from .python_to_sqlite import PythonToSQLite
2
+ from .sqlite_module_importer import SQLiteModuleImporter
3
+ from .sqlite_module_loader import SQLiteModuleLoader
4
+ from .sqlite_meta_path_finder import SQLiteMetaPathFinder
5
+
6
+ __all__ = [
7
+ "PythonToSQLite",
8
+ "SQLiteModuleImporter",
9
+ "SQLiteModuleLoader",
10
+ "SQLiteMetaPathFinder",
11
+ ]
module_bank/cli.py ADDED
@@ -0,0 +1,83 @@
1
+ import argparse
2
+ from pathlib import Path
3
+
4
+
5
+ def main():
6
+ parser = argparse.ArgumentParser(description="Python模块SQLite打包工具")
7
+ subparsers = parser.add_subparsers(dest="command", help="命令")
8
+
9
+ # 打包命令
10
+ pack_parser = subparsers.add_parser("pack", help="打包模块到SQLite")
11
+ pack_parser.add_argument("source", help="源文件或目录")
12
+ pack_parser.add_argument("--db", default="modules.db", help="数据库文件路径")
13
+ pack_parser.add_argument("--name", help="模块名(默认从文件名推断)")
14
+
15
+ # 列出命令
16
+ list_parser = subparsers.add_parser("list", help="列出数据库中的模块")
17
+ list_parser.add_argument("--db", default="modules.db", help="数据库文件路径")
18
+
19
+ # 删除原代码
20
+ delete_source_parser = subparsers.add_parser(
21
+ "delete_source", help="删除数据库中的源代码"
22
+ )
23
+ delete_source_parser.add_argument(
24
+ "--db", default="modules.db", help="数据库文件路径"
25
+ )
26
+ delete_source_parser.add_argument("--module", help="要删除的模块名")
27
+
28
+ # 安装命令
29
+ install_parser = subparsers.add_parser("install", help="安装SQLite导入器")
30
+ install_parser.add_argument("--db", default="modules.db", help="数据库文件路径")
31
+
32
+ args = parser.parse_args()
33
+
34
+ if args.command == "pack":
35
+ from .python_to_sqlite import PythonToSQLite
36
+
37
+ packer = PythonToSQLite(args.db)
38
+
39
+ if Path(args.source).is_dir():
40
+ packer.pack_directory(args.source)
41
+ print(f"已打包目录: {args.source}")
42
+ else:
43
+ packer.pack_module(args.source, args.name)
44
+ print(f"已打包模块: {args.source}")
45
+
46
+ elif args.command == "list":
47
+ from .python_to_sqlite import PythonToSQLite
48
+
49
+ packer = PythonToSQLite(args.db)
50
+ modules = packer.list_modules()
51
+
52
+ print(f"数据库中的模块 ({args.db}):")
53
+ for module in modules:
54
+ package_flag = " [包]" if module["is_package"] else ""
55
+ print(f" - {module['module_name']}{package_flag}")
56
+
57
+ elif args.command == "delete_source":
58
+ from .python_to_sqlite import PythonToSQLite
59
+
60
+ packer = PythonToSQLite(args.db)
61
+ if args.module:
62
+ packer.delete_source_code(args.module)
63
+ else:
64
+ packer.delete_source_code(None)
65
+
66
+ elif args.command == "install":
67
+ from .python_to_sqlite import PythonToSQLite
68
+
69
+ packer = PythonToSQLite(args.db)
70
+ packer.install_importer()
71
+ print(f"已安装SQLite导入器,可以从数据库导入模块了!")
72
+
73
+ # 保持程序运行以便交互使用
74
+ import code
75
+
76
+ code.interact(local=locals())
77
+
78
+ else:
79
+ parser.print_help()
80
+
81
+
82
+ if __name__ == "__main__":
83
+ main()
@@ -0,0 +1,133 @@
1
+ import sys
2
+ from pathlib import Path
3
+ from typing import List
4
+ from .sqlite_module_importer import SQLiteModuleImporter
5
+ from .sqlite_meta_path_finder import SQLiteMetaPathFinder
6
+
7
+
8
+ class PythonToSQLite:
9
+ """Python到SQLite的打包工具"""
10
+
11
+ def __init__(self, db_path: str = "python_modules.db"):
12
+ self.db_path = db_path
13
+ self.importer = SQLiteModuleImporter(db_path)
14
+
15
+ def pack_directory(
16
+ self,
17
+ directory_path: str,
18
+ include_patterns: List[str] = None,
19
+ exclude_patterns: List[str] = None,
20
+ ):
21
+ """打包整个目录 - 修复版"""
22
+ directory = Path(directory_path)
23
+ package_name = directory.name # 包名
24
+
25
+ if include_patterns is None:
26
+ include_patterns = ["*.py"]
27
+ if exclude_patterns is None:
28
+ exclude_patterns = ["__pycache__", "*.pyc"]
29
+
30
+ # 遍历目录
31
+ for py_file in directory.rglob("*.py"):
32
+ # 检查排除模式
33
+ if any(py_file.match(pattern) for pattern in exclude_patterns):
34
+ continue
35
+
36
+ # 检查包含模式
37
+ if any(py_file.match(pattern) for pattern in include_patterns):
38
+ # 计算相对于包的路径
39
+ rel_path = py_file.relative_to(directory)
40
+ module_parts = list(rel_path.parts)
41
+ module_parts[-1] = module_parts[-1][:-3] # 去掉.py
42
+
43
+ if module_parts[-1] == "__init__":
44
+ # 这是包
45
+ if len(module_parts) > 1:
46
+ # 子包,例如:subpackage/__init__.py
47
+ module_name = f"{package_name}.{'.'.join(module_parts[:-1])}"
48
+ else:
49
+ # 主包,例如:__init__.py
50
+ module_name = package_name
51
+
52
+ print(f"打包包: {module_name} (来自: {py_file})")
53
+ self.importer.add_module(
54
+ module_name,
55
+ py_file.read_text(encoding="utf-8"),
56
+ is_package=True,
57
+ )
58
+ else:
59
+ # 普通模块
60
+ module_name = f"{package_name}.{'.'.join(module_parts)}"
61
+
62
+ print(f"打包模块: {module_name} (来自: {py_file})")
63
+ self.importer.add_module(
64
+ module_name,
65
+ py_file.read_text(encoding="utf-8"),
66
+ is_package=False,
67
+ )
68
+
69
+ def pack_module(self, module_path: str, module_name: str = None):
70
+ """打包单个模块"""
71
+ module_path = Path(module_path)
72
+
73
+ if module_name is None:
74
+ module_name = module_path.stem
75
+
76
+ with open(module_path, "r", encoding="utf-8") as f:
77
+ source_code = f.read()
78
+
79
+ print(f"打包独立模块: {module_name} (来自: {module_path})")
80
+ self.importer.add_module(module_name, source_code, is_package=False)
81
+
82
+ def install_importer(self):
83
+ """安装导入器到sys.meta_path"""
84
+ finder = SQLiteMetaPathFinder(self.db_path)
85
+ # 添加到meta_path开头,优先于文件系统查找
86
+ sys.meta_path.insert(0, finder)
87
+ return finder
88
+
89
+ def list_modules(self):
90
+ """列出数据库中的所有模块"""
91
+ cursor = self.importer.connection.execute(
92
+ "SELECT module_name, is_package FROM python_modules ORDER BY module_name"
93
+ )
94
+ return [dict(row) for row in cursor.fetchall()]
95
+
96
+ def delete_source_code(self, module_name):
97
+ """删除数据库中的源代码"""
98
+ if module_name is None:
99
+ cursor = self.importer.connection.execute(
100
+ "UPDATE python_modules SET source_code = NULL"
101
+ )
102
+ else:
103
+ cursor = self.importer.connection.execute(
104
+ "UPDATE python_modules SET source_code = NULL WHERE module_name = ?",
105
+ (module_name,),
106
+ )
107
+ self.importer.connection.commit()
108
+ return cursor.rowcount > 0
109
+
110
+ def verify_package_structure(self):
111
+ """验证包的完整性"""
112
+ cursor = self.importer.connection.execute(
113
+ "SELECT module_name, is_package FROM python_modules"
114
+ )
115
+ modules = {row["module_name"]: row["is_package"] for row in cursor.fetchall()}
116
+
117
+ print("数据库中的模块结构:")
118
+ for module_name, is_package in sorted(modules.items()):
119
+ package_flag = " [包]" if is_package else ""
120
+ print(f" - {module_name}{package_flag}")
121
+
122
+ # 检查包的完整性
123
+ for module_name, is_package in modules.items():
124
+ if "." in module_name and not is_package:
125
+ parent_package = module_name.rsplit(".", 1)[0]
126
+ if parent_package not in modules:
127
+ print(
128
+ f"警告:模块 {module_name} 的父包 {parent_package} 不在数据库中"
129
+ )
130
+ elif not modules[parent_package]:
131
+ print(
132
+ f"警告:模块 {module_name} 的父包 {parent_package} 不是一个包"
133
+ )
@@ -0,0 +1,53 @@
1
+ import sqlite3
2
+ import importlib
3
+ import importlib.abc
4
+ import importlib.util
5
+ from .sqlite_module_loader import SQLiteModuleLoader
6
+
7
+
8
+ class SQLiteMetaPathFinder(importlib.abc.MetaPathFinder):
9
+ """SQLite元路径查找器"""
10
+
11
+ def __init__(self, db_path: str):
12
+ self.db_path = db_path
13
+ self.connection = sqlite3.connect(db_path)
14
+ self.connection.row_factory = sqlite3.Row
15
+ # 缓存模块查找结果
16
+ self.module_cache = {}
17
+ self._load_module_cache()
18
+
19
+ def _load_module_cache(self):
20
+ """加载所有模块到缓存"""
21
+ cursor = self.connection.execute(
22
+ "SELECT module_name, is_package FROM python_modules"
23
+ )
24
+ for row in cursor.fetchall():
25
+ self.module_cache[row["module_name"]] = row["is_package"]
26
+
27
+ def find_spec(self, fullname, path=None, target=None):
28
+ """查找模块规范"""
29
+ # 检查模块是否在数据库中
30
+ if fullname in self.module_cache:
31
+ # 创建模块规范
32
+ spec = importlib.util.spec_from_loader(
33
+ fullname,
34
+ SQLiteModuleLoader(self.connection, fullname, self.db_path),
35
+ origin=f"sqlite://{self.db_path}",
36
+ is_package=self.module_cache[fullname],
37
+ )
38
+ return spec
39
+
40
+ # 如果不是完整模块名,检查是否可能是包的子模块
41
+ # 例如:my_package.package_module
42
+ if "." in fullname:
43
+ # 检查完整模块名是否在数据库中
44
+ if fullname in self.module_cache:
45
+ spec = importlib.util.spec_from_loader(
46
+ fullname,
47
+ SQLiteModuleLoader(self.connection, fullname, self.db_path),
48
+ origin=f"sqlite://{self.db_path}",
49
+ is_package=self.module_cache[fullname],
50
+ )
51
+ return spec
52
+
53
+ return None
@@ -0,0 +1,107 @@
1
+ import sqlite3
2
+ import marshal
3
+ from pathlib import Path
4
+ from typing import Dict
5
+
6
+
7
+ class SQLiteModuleImporter:
8
+ """从SQLite数据库导入Python模块的导入器"""
9
+
10
+ def __init__(self, db_path: str):
11
+ self.db_path = db_path
12
+ self.connection = sqlite3.connect(db_path)
13
+ self.connection.row_factory = sqlite3.Row
14
+ self._create_tables()
15
+
16
+ def _create_tables(self):
17
+ """创建存储模块的数据库表"""
18
+ self.connection.execute(
19
+ """
20
+ CREATE TABLE IF NOT EXISTS python_modules (
21
+ module_name TEXT PRIMARY KEY,
22
+ source_code TEXT,
23
+ bytecode BLOB,
24
+ is_package BOOLEAN,
25
+ metadata TEXT,
26
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
27
+ )
28
+ """
29
+ )
30
+ self.connection.commit()
31
+
32
+ def add_module(
33
+ self,
34
+ module_name: str,
35
+ source_code: str,
36
+ is_package: bool = False,
37
+ metadata: Dict = None,
38
+ ):
39
+ """添加模块到数据库"""
40
+ # 编译为字节码
41
+ bytecode = compile(source_code, f"<sqlite_module:{module_name}>", "exec")
42
+ bytecode_blob = marshal.dumps(bytecode)
43
+
44
+ metadata_str = str(metadata) if metadata else "{}"
45
+
46
+ self.connection.execute(
47
+ """
48
+ INSERT OR REPLACE INTO python_modules
49
+ (module_name, source_code, bytecode, is_package, metadata)
50
+ VALUES (?, ?, ?, ?, ?)
51
+ """,
52
+ (module_name, source_code, bytecode_blob, is_package, metadata_str),
53
+ )
54
+ self.connection.commit()
55
+
56
+ def add_module_from_file(self, file_path: str, module_name: str = None):
57
+ """从文件添加模块"""
58
+ file_path = Path(file_path)
59
+
60
+ if module_name is None:
61
+ # 从文件名推导模块名
62
+ module_name = file_path.stem
63
+
64
+ with open(file_path, "r", encoding="utf-8") as f:
65
+ source_code = f.read()
66
+
67
+ self.add_module(module_name, source_code)
68
+
69
+ def add_package(self, package_path: str, package_name: str = None):
70
+ """添加整个包到数据库"""
71
+ package_path = Path(package_path)
72
+
73
+ if package_name is None:
74
+ package_name = package_path.name
75
+
76
+ # 添加包目录下的所有.py文件
77
+ for py_file in package_path.rglob("*.py"):
78
+ # 计算模块名
79
+ rel_path = py_file.relative_to(package_path)
80
+ module_parts = list(rel_path.parts)
81
+ module_parts[-1] = module_parts[-1][:-3] # 去掉.py
82
+
83
+ if module_parts[-1] == "__init__":
84
+ # 包本身
85
+ module_name = package_name
86
+ if len(module_parts) > 1:
87
+ # 子包
88
+ module_name = f"{package_name}.{'.'.join(module_parts[:-1])}"
89
+ self.add_module(
90
+ module_name,
91
+ py_file.read_text(encoding="utf-8"),
92
+ is_package=True,
93
+ )
94
+ else:
95
+ # 包内的模块
96
+ if len(module_parts) == 1:
97
+ # 直接子模块
98
+ module_name = f"{package_name}.{module_parts[0]}"
99
+ else:
100
+ # 子包内的模块
101
+ module_name = f"{package_name}.{'.'.join(module_parts)}"
102
+
103
+ self.add_module(
104
+ module_name,
105
+ py_file.read_text(encoding="utf-8"),
106
+ is_package=False,
107
+ )
@@ -0,0 +1,63 @@
1
+ import sqlite3
2
+ import importlib
3
+ import importlib.abc
4
+ import marshal
5
+ import types
6
+
7
+
8
+ class SQLiteModuleLoader(importlib.abc.Loader):
9
+ """SQLite模块加载器"""
10
+
11
+ def __init__(
12
+ self, db_connection: sqlite3.Connection, module_name: str, db_path: str = None
13
+ ):
14
+ self.db_connection = db_connection
15
+ self.module_name = module_name
16
+ self.db_path = db_path
17
+ self.db_connection.row_factory = sqlite3.Row
18
+
19
+ def create_module(self, spec):
20
+ """创建模块对象"""
21
+ # 获取模块信息
22
+ cursor = self.db_connection.execute(
23
+ "SELECT is_package FROM python_modules WHERE module_name = ?",
24
+ (self.module_name,),
25
+ )
26
+ row = cursor.fetchone()
27
+
28
+ if row and row["is_package"]:
29
+ # 创建包模块
30
+ module = types.ModuleType(self.module_name)
31
+ module.__path__ = [] # 包需要有__path__属性
32
+ module.__package__ = self.module_name
33
+ return module
34
+ else:
35
+ # 创建普通模块
36
+ return None # 使用默认创建方式
37
+
38
+ def exec_module(self, module):
39
+ """执行模块代码"""
40
+ cursor = self.db_connection.execute(
41
+ "SELECT bytecode, source_code, is_package FROM python_modules WHERE module_name = ?",
42
+ (self.module_name,),
43
+ )
44
+ row = cursor.fetchone()
45
+
46
+ if not row:
47
+ raise ImportError(f"No module named '{self.module_name}' in database")
48
+
49
+ # 从字节码加载
50
+ bytecode = marshal.loads(row["bytecode"])
51
+
52
+ # 在模块的命名空间中执行字节码
53
+ exec(bytecode, module.__dict__)
54
+
55
+ # 如果是包,设置__path__属性
56
+ if row["is_package"]:
57
+ module.__path__ = []
58
+ module.__package__ = self.module_name
59
+
60
+ # 设置模块的__file__属性为数据库路径
61
+ module.__file__ = f"sqlite://{self.db_path}/{self.module_name}"
62
+
63
+ return module
@@ -0,0 +1,259 @@
1
+ Metadata-Version: 2.4
2
+ Name: module_bank
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ License-File: LICENSE
6
+ Requires-Python: >=3.7
7
+ Description-Content-Type: text/markdown
8
+
9
+ # Python Module Bank - SQLite 模块打包系统
10
+
11
+ 一个将Python模块打包到SQLite数据库,并支持从数据库直接导入模块的工具系统。
12
+
13
+ ## 🌟 特性
14
+
15
+ - **单文件分发** - 将所有模块打包到单个SQLite数据库文件
16
+ - **源代码保护** - 模块以编译后的字节码形式存储
17
+ - **动态导入** - 运行时直接从数据库加载模块,无需文件系统
18
+ - **完整包支持** - 支持包结构和子模块导入
19
+ - **CLI工具** - 提供完整的命令行接口
20
+ - **导入钩子** - 无缝集成Python导入系统
21
+
22
+ ## 📦 安装
23
+
24
+ ### 从源码安装
25
+
26
+ ```bash
27
+ git clone http://124.71.68.6:3000/chakcy/module_bank.git
28
+ cd module-bank
29
+ pip install -e .
30
+ ```
31
+
32
+ ### 依赖要求
33
+
34
+ - Python 3.7+
35
+ - 无需额外依赖(仅使用标准库)
36
+
37
+ ## 🚀 快速开始
38
+
39
+ ### 1. 创建示例模块
40
+
41
+ ```python
42
+ # my_module.py
43
+ def hello():
44
+ print("Hello from my_module!")
45
+ return "success"
46
+ ```
47
+
48
+ ### 2. 打包模块到数据库
49
+
50
+ ```python
51
+ # pack_example.py
52
+ from module_bank import PythonToSQLite
53
+
54
+ packer = PythonToSQLite("my_modules.db")
55
+ packer.pack_module("my_module.py", "my_module")
56
+ packer.pack_directory("my_package/")
57
+ ```
58
+
59
+ ### 3. 从数据库导入
60
+
61
+ ```python
62
+ from module_bank import PythonToSQLite
63
+
64
+ # 安装导入器
65
+ packer = PythonToSQLite("my_modules.db")
66
+ finder = packer.install_importer()
67
+
68
+ # 现在可以从数据库导入模块了!
69
+ import my_module
70
+ import my_package.package_module
71
+
72
+ my_module.hello()
73
+ my_package.package_module.hello()
74
+ ```
75
+
76
+ ## 📖 详细使用
77
+
78
+ ### 命令行工具
79
+
80
+ ```python
81
+ # 打包模块或目录
82
+ mb pack my_package --db modules.db
83
+
84
+ # 列出数据库中的模块
85
+ mb list --db modules.db
86
+
87
+ # 安装导入器并进入交互模式
88
+ mb install --db modules.db
89
+ ```
90
+
91
+ ### 编程接口
92
+
93
+ #### 打包模块
94
+
95
+ ```python
96
+ from module_bank import PythonToSQLite
97
+
98
+ packer = PythonToSQLite("modules.db")
99
+
100
+ # 打包单个模块
101
+ packer.pack_module("module.py", "module_name")
102
+
103
+ # 打包整个目录(自动识别包结构)
104
+ packer.pack_directory("my_package/")
105
+
106
+ # 验证包结构
107
+ packer.verify_package_structure()
108
+ ```
109
+
110
+ #### 导入模块
111
+
112
+ ```python
113
+ from module_bank import PythonToSQLite
114
+ import sys
115
+
116
+ packer = PythonToSQLite("modules.db")
117
+
118
+ # 安装导入器到sys.meta_path
119
+ finder = packer.install_importer()
120
+
121
+ # 列出所有可用模块
122
+ modules = packer.list_modules()
123
+ for module in modules:
124
+ print(f"{module['module_name']} {'[包]' if module['is_package'] else ''}")
125
+
126
+ # 导入数据库中的模块
127
+ import my_package
128
+ import my_package.submodule
129
+ ```
130
+
131
+ ## 🏗️ 架构设计
132
+
133
+ ### 核心组件
134
+
135
+ ```python
136
+ src/module_bank/
137
+ ├── python_to_sqlite.py # 主打包类
138
+ ├── sqlite_module_importer.py # 数据库存储管理器
139
+ ├── sqlite_meta_path_finder.py # 元路径查找器
140
+ ├── sqlite_module_loader.py # 模块加载器
141
+ ├── cli.py # 命令行接口
142
+ └── __init__.py # 模块导出
143
+ ```
144
+
145
+ ### 数据流
146
+
147
+ ```text
148
+ 1. 打包阶段:
149
+ .py文件 → 编译为字节码 → 存储到SQLite数据库
150
+
151
+ 2. 导入阶段:
152
+ 导入请求 → MetaPathFinder查找 → ModuleLoader加载 → 执行模块
153
+ ```
154
+
155
+ ### 数据库模式
156
+
157
+ ```sql
158
+ CREATE TABLE python_modules (
159
+ module_name TEXT PRIMARY KEY,
160
+ source_code TEXT, -- 源代码(可选)
161
+ bytecode BLOB, -- 编译后的字节码
162
+ is_package BOOLEAN, -- 是否是包
163
+ metadata TEXT, -- 元数据(JSON格式)
164
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
165
+ )
166
+ ```
167
+
168
+ ## 🔧 高级功能
169
+
170
+ ### 排除模式
171
+
172
+ ```python
173
+ # 打包时排除特定文件
174
+ packer.pack_directory(
175
+ "my_project/",
176
+ exclude_patterns=["*_test.py", "*.pyc", "__pycache__"]
177
+ )
178
+ ```
179
+
180
+ ### 元数据存储
181
+
182
+ ```python
183
+ # 为模块添加元数据
184
+ packer.importer.add_module(
185
+ "my_module",
186
+ source_code,
187
+ is_package=False,
188
+ metadata={"version": "1.0", "author": "me"}
189
+ )
190
+ ```
191
+
192
+ ### 混合导入
193
+
194
+ ```python
195
+ # 可以同时使用文件系统和数据库导入
196
+ # 数据库导入器优先级更高
197
+ import sys
198
+ from module_bank import PythonToSQLite
199
+
200
+ packer = PythonToSQLite("modules.db")
201
+ finder = packer.install_importer() # 插入到meta_path开头
202
+
203
+ # 如果需要文件系统优先,可以调整插入位置
204
+ sys.meta_path.append(finder)
205
+ ```
206
+
207
+ ## ⚠️ 注意事项
208
+
209
+ ### 安全性
210
+
211
+ - 模块字节码直接执行,确保数据库来源可信
212
+ - 生产环境建议添加代码签名验证
213
+
214
+ ### 兼容性
215
+
216
+ - 字节码不跨Python版本兼容
217
+ - 不支持C扩展模块
218
+ - 不支持需要文件系统资源的模块(如__file__依赖)
219
+
220
+ ### 性能
221
+
222
+ - **启动时**:有一次性数据库查询和反序列化开销
223
+ - **运行时**:与传统导入性能相同(使用sys.modules缓存)
224
+ - **最佳适用**:长期运行的服务、桌面应用
225
+
226
+ ### 更新模块
227
+
228
+ ```python
229
+ # 重新打包会自动更新
230
+ packer.pack_module("updated_module.py", "module_name")
231
+ ```
232
+
233
+ ### 删除模块
234
+
235
+ ```sql
236
+ -- 直接从数据库删除
237
+ DELETE FROM python_modules WHERE module_name = 'module_to_remove';
238
+ ```
239
+
240
+ ### 备份与恢复
241
+
242
+ ```bash
243
+ # 数据库是单个文件,易于备份
244
+ cp modules.db modules.backup.db
245
+
246
+ # 恢复
247
+ cp modules.backup.db modules.db
248
+ ```
249
+
250
+ ## 📚 应用场景
251
+
252
+ 1. 商业软件分发 - 保护源代码知识产权
253
+ 2. 插件系统 - 动态加载数据库中的插件模块
254
+ 3. 教育平台 - 安全分发练习代码
255
+ 4. 微服务 - 打包多个服务模块到单个文件
256
+ 5. 嵌入式系统 - 减少文件系统依赖
257
+
258
+ ---
259
+ **注意**: 本工具主要用于模块分发和部署场景,不适合开发阶段的频繁修改。
@@ -0,0 +1,11 @@
1
+ module_bank/__init__.py,sha256=Ah6kj8zaAwXv06tyyQy0ScHHqnNU3o97gzPMsIZfz6Y,343
2
+ module_bank/cli.py,sha256=_owbGoZm2AwwjFMrXToVvMIc4TuZeY8C_MzkIL6XDAc,2866
3
+ module_bank/python_to_sqlite.py,sha256=-6nv2qHtGunNDf_wiisCkUZbACZI5aDBkzNjrINOTCs,5314
4
+ module_bank/sqlite_meta_path_finder.py,sha256=hBt0GizQpu3XjlLZpb1AKwf2qbZnYr1GQhuG9IC56Eo,1964
5
+ module_bank/sqlite_module_importer.py,sha256=vPxBfK_sE4sD0mw8kmCXLTqAAVWWcrIdrOe43-I-TIc,3651
6
+ module_bank/sqlite_module_loader.py,sha256=8lVI9xDT3R3n2Rw2mfuvUzUDLJDzXeSLeSm9wNNh8xY,2040
7
+ module_bank-0.1.0.dist-info/METADATA,sha256=4lsDUYdc0uw-RNerQa8xvgbiHxWFImneBR5dV9GdrXM,5650
8
+ module_bank-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
9
+ module_bank-0.1.0.dist-info/entry_points.txt,sha256=CF6TIxJcnS32_neyYNNoU8u7divGlekRca2jLZcya_Q,44
10
+ module_bank-0.1.0.dist-info/licenses/LICENSE,sha256=yqHVHGIcK1r05NJdf_BzMXNgdO1cQsG1me3A015Addo,1082
11
+ module_bank-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ mb = module_bank.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 chakcy
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.