-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
python_setup_cn
MMKV 是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。从 2015 年中至今在微信上使用,其性能和稳定性经过了时间的验证。现已移植到 Android / macOS / Windows / Python (on POSIX & Windows) / Golang (on POSIX) 平台,一并开源。
- Python 2.7 或以上版本;
- CMake 3.8.0 或以上版本;
- C++ 编译器需支持 C++ 20 标准;
- MMKV 支持 Linux(Ubuntu, Arch Linux, CentOS, Gentoo)、Unix(macOS, FreeBSD, OpenBSD) 等 POSIX 平台,以及Windows平台。
- 从 GitHub 拉取源码:
git clone https://github.com/Tencent/MMKV.git
- 解决 pybind11 相关依赖。
2.1 拉取 pybind11 (v2.5.0) 源码:
cd MMKV
git submodule update --init --recursive
2.2 如果是 Linux,需要安装 python-dev (for Python 2.x),或 python3-dev (for Pythond 3.x)。如果是 macOS 或 Windows,则无需安装。具体参见 pybind11 docs。
例如,假设我们在 Ubuntu 上使用 Python 3.x:
sudo apt-get install python3-dev
- 编译并安装 MMKV for Python 原生库 (安装时可能需要
root
权限)。假设我们用的是 Python 3.x:
cd ./Python
python3 setup.py install
# or if you're not root
sudo python3 setup.py install
这就全部 OK 了。
- 注: 如果你不想安装 MMKV 到系统,你可以只编译原生库:
cd ./Python
cmake -B build
cmake --build build --config Release -j 8
留意 cmake
的输出,确认用了哪个 Python 来编译 MMKV。日志大概是这样:
-- Found PythonInterp: /usr/bin/python3.6 (found version "3.6.9") .
如果发现不是你想用的版本 (例如你要用 Python 2.7),你可以给 cmake
设置参数 PYBIND11_PYTHON_VERSION
:
cmake -DPYBIND11_PYTHON_VERSION=2.7 ..
编译完成后,将生成的 mmkv 动态库 (具体名字不同操作系统不同设备不一样,例如可能叫 mmkv.cpython-36m-x86_64-linux-gnu.so
或mmkv.lib
) 拷到 Python 的库目录 PYTHONPATH
。如果你用 Python 3,也可以直接拷到脚本目录下。
- 测试 MMKV:
# cd 到 MMKV/Python
python3 demo.py
python3 unit_test.py
MMKV 的使用非常简单,所有变更立马生效,无需调用 save
、sync
。
-
在程序启动时初始化 MMKV,设定 MMKV 的根目录,例如在
main()
函数里:import mmkv if __name__ == '__main__': mmkv.MMKV.initializeMMKV(tempfile.gettempdir() + '/mmkv')
-
MMKV 提供一个全局的实例,可以直接使用:
kv = mmkv.MMKV.defaultMMKV() kv.set(True, 'bool') print('bool = ', kv.getBool('bool')) kv.set(-1 * (2 ** 31), 'int32') print('int32 = ', kv.getInt('int32')) kv.set((2 ** 32) - 1, 'uint32') print('uint32 = ', kv.getUInt('uint32')) kv.set(2 ** 63, 'int64') print('int64 = ', kv.getLongInt('int64')) kv.set((2 ** 64) - 1, 'uint64') print('uint64 = ', kv.getLongUInt('uint64')) kv.set(3.1415926, 'float') print('float = ', kv.getFloat('float')) kv.set('Hello world, MMKV for Python!', 'string') print('string = ', kv.getString('string')) lst = range(0, 10) kv.set(bytes(lst), 'bytes') bt = kv.getBytes('bytes') print('raw bytes = ', bt, ', decoded bytes = ', list(bt))
可以看到,MMKV 在使用上还是比较简单的。
-
删除 & 查询:
kv = mmkv.MMKV.defaultMMKV() print('keys before remove:', sorted(kv.keys())) kv.remove('bool') print('"bool" exist after remove: ', ('bool' in kv)) kv.remove(['int32', 'float']) print('keys after remove:', sorted(kv.keys()))
-
如果不同业务需要区别存储,也可以单独创建自己的实例:
kv = mmkv.MMKV('test_python') kv.set(True, 'bool')
-
如果业务需要多进程访问,那么在初始化的时候加上标志位
MMKV.MULTI_PROCESS_MODE
:kv = mmkv.MMKV('test_python', mmkv.MMKVMode.MultiProcess) kv.set(True, 'bool')
-
支持以下基础类型:
Boolean, int, float
注意: 由于 protobuf 的具体实现限制,整数类型按
int32, uint32, int64, uint64
划分,有不同的序列化/反序列化实现。所以在 get 的时候,需要按照 value 的可能范围,调用不同的 getXXXInt() 函数。具体每个整数类型的取值范围,可以参考MMKV/Python/unit_test.py
。set 的时候无需区分,MMKV 会自动选择最小的类型进行存储。 -
支持以下类:
str, bytes
-
MMKV 默认不打印任何日志,你可以在初始化的时候打开日志开关:
mmkv.MMKV.initializeMMKV(tempfile.gettempdir() + '/mmkv', mmkv.MMKVLogLevel.Info)
-
MMKV 会将日志输出到
stdout
,对于解析器执行、现网问题跟进都不方便。你可以在程序启动时重定向 MMKV 的日志。实现(logLevel: mmkv.MMKVLogLevel, file: str, line: int, function: str, message: str) -> None
类型的回调函数,注册为日志 handler. 然后记得在程序退出之前反注册日志 handler (或调用MMKV.onExit()
),否则程序可能无法正常退出。
def logger(log_level, file, line, function, message):
level = {
mmkv.MMKVLogLevel.NoLog : 'N',
mmkv.MMKVLogLevel.Debug : 'D',
mmkv.MMKVLogLevel.Info : 'I',
mmkv.MMKVLogLevel.Warning : 'W',
mmkv.MMKVLogLevel.Error : 'E'
}
# use your logging tools instead of print()
print('[{0}] <{1}:{2}:{3}> {4}'.format(level[log_level], file, line, function, message))
if __name__ == '__main__':
# enable logging & redirect logging
mmkv.MMKV.initializeMMKV(tempfile.gettempdir() + '/mmkv', mmkv.MMKVLogLevel.Info, logger)
# some logic
...
# unregister before exit, otherwise the script won't exit properly
mmkv.MMKV.unRegisterLogHandler()
# or just call onExit() will do the job
# mmkv.MMKV.onExit()
-
MMKV 提供了备份和恢复接口,可用于备份数据到其他目录,并稍后恢复原有数据。
root_dir = tempfile.gettempdir() + '/mmkv_backup' // backup one instance ret = mmkv.MMKV.backupOneToDirectory(mmap_id, root_dir) // backup all instances count = mmkv.MMKV.backupAllToDirectory(root_dir) // restore one instance ret = mmkv.MMKV.restoreOneFromDirectory(mmap_id, root_dir) // restore all instances count = mmkv.MMKV.restoreAllFromDirectory(root_dir)
-
v1.3.0 起你可以升级 MMKV 到 key 自动过期特性。注意这是格式不向下兼容的升级操作。一旦升级到 key 自动过期,旧版 MMKV (<= v1.2.16) 将无法正常读写该文件。
-
全局过期. 最简单的用法是给整个文件设定统一的过期间隔。
// expire in a day kv.enableAutoKeyExpire(24 * 60 * 60);
或者,你可以选择只升级 MMKV,但不设置全局过期间隔。这种情况下,默认每个 key 不过期。
// enable auto key expiration without global duration kv.enableAutoKeyExpire(0);
-
单独过期. 你可以给每个 key 设置单独的过期间隔,区分于文件的全局过期间隔。注意,你仍然需要先升级 MMKV 为 key 自动过期。
// enable auto key expiration with an hour duration kv.enableAutoKeyExpire(60 * 60); // set a key with the file's global expiration duration, aka 60 * 60 kv.set("some value", "key_1"); // set a special key that expires in two hours kv.set("some value", "key_2", 2 * 60 * 60); // set a special key that never expires kv.set("some value", "key_3", 0);
或者,你可以选择只升级 MMKV,但不设置全局过期间隔。这种情况下,默认每个 key 不过期。
// enable auto key expiration without global duration kv.enableAutoKeyExpire(0); // set a key that never expires kv.set("some value", "key_1"); // set a special key that expires in an hour kv.set("some value", "key_2", 60 * 60);
-
过期间隔的单位是秒。你可以使用任意自定义间隔,例如一周是
7 * 24 * 60 * 60
。
MMKV is published under the BSD 3-Clause license. For details check out the LICENSE.TXT.
Check out the CHANGELOG.md for details of change history.
If you are interested in contributing, check out the CONTRIBUTING.md, also join our Tencent OpenSource Plan.
To give clarity of what is expected of our members, MMKV has adopted the code of conduct defined by the Contributor Covenant, which is widely used. And we think it articulates our values well. For more, check out the Code of Conduct.
Check out the FAQ first. Should there be any questions, don't hesitate to create issues.
User privacy is taken very seriously: MMKV does not obtain, collect or upload any personal information. Please refer to the MMKV SDK Personal Information Protection Rules for details.
- In English
- 中文
- In English
- 中文
- In English
- 中文
-
In English
-
中文
-
Golang