JRT v.2.9.0 的发布时间是 2022 年 1 月 22 日,距现在有四个多月了。
所以,这个功能版本的更新日志长度,可能会让你怀疑是不是 JRT v3 提前上线了,当然,作为一个功能版本,我们依然保持了于 JRT 2.9.0 的向后兼容,如果你没有写一些”黑魔法“代码的话。
完整的更新日志可以在这里看到:Release JRT v2.10.0 · FHU-yezi/JianshuResearchTools
考虑到有些用户无法顺畅地访问 GitHub,我们也为大家准备了图片版本的更新日志:
[图片上传失败...(image-9bbeb6-1654069189571)]
下面,我们将从几个方面讨论这一版本的变化。
(这是一篇面向开发者的文章,其中不包含基于 JRT 的服务的内容)
性能优化
首先,我们对 article.GetArticleHtml
进行了性能优化,具体更改如下:
[图片上传失败...(image-10e24a-1654069189571)]
现在,JRT 中有很多函数依赖正则表达式进行数据获取与清洗。我们的实践表明,使用正则表达式可以在开发效率与性能间取得比较完美的平衡。
同时,我们也将 assert_funcs
模块中的大部分断言函数改为了基于正则表达式的实现,以 assert_funcs.AssertJianshuUrl
函数为例:
[图片上传失败...(image-6ab473-1654069189571)]
所有正则表达式均在初始化时完成编译,以优化运行时性能。经过测试,这一操作对模块的初始化时间没有明显影响。
经测试,基于正则表达式的断言函数实现比之前基于字符匹配的实现性能略有下降,但在实际应用过程中,基于正则表达式的实现能使用纯计算方式筛选掉更多错误的资源地址,从而降低了访问服务器进行验证的频率,而后者的开销与前者相差几个数量级。
同时,所有在断言函数中使用到的正则表达式均在 assert_funcs
模块中可用,列表如下:
- assert_funcs.JIANSHU_URL_REGEX
- assert_funcs.JIANSHU_USER_URL_REGEX
- assert_funcs.JIANSHU_ARTICLES_URL_REGEX
- assert_funcs.JIANSHU_NOTEBOOK_URL_REGEX
- assert_funcs.JIANSHU_COLLECTION_URL_REGEX
- assert_funcs.JIANSHU_ISLAND_URL_REGEX
- assert_funcs.JIANSHU_ISLAND_POST_URL_REGEX
您可以使用这些正则表达式实现更多功能。需要注意的是,这些正则表达式只能匹配到开头到结尾中没有任何其它内容的字符串,因此,您无法将其用于识别文章中可能的 URL。
鉴于这些正则表达式的用途,我们目前没有对此特性进行修改的计划。
功能变动
现在,objects
模块中的对象在创建时会对资源进行完整的检查,包括上文提到的基于正则表达式的检查,以及访问服务器的检查,因此,创建资源对象不再是低时间开销的操作。
这一变更在语法上是向后兼容的,但如果您的代码中涉及大量的对象构建操作,升级到 JRT v2.10.0 后,可能会因此产生性能瓶颈。
现在,我们对 objects
模块中资源对象的推荐用法如下:
import JianshuResearchTools.objects as jobjs
from JianshuResearchTools.exceptions import InputError, ResourceError
input_url = input("请输入用户 URL:")
try:
user = jobjs.User(input_url)
except InputError:
print("您输入的 URL 有误,请检查!")
except ResourceError:
print("该用户不存在或账号状态异常,请检查!")
else:
print(f"该用户的昵称为:{user.name}")
通过这种方式,您不再需要显式地对资源的可用性进行检查,只需创建对象,然后捕获可能产生的异常,并执行对应的处理逻辑。
在接下来的版本中,我们也会加入禁用该检测的方式,您可以对可信的数据源禁用这一检测来提高性能,但请注意,我们假定对象在创建后,其资源地址始终是有效的,如果您传入了无效的资源地址,在尝试获取其数据时可能会产生未被捕获的异常。
另一个对 objects
模块的变动是与缓存相关的,我们重写了缓存逻辑,并加入了一系列函数,允许开发者对缓存进行更多控制,它们包括:
- objects.get_cache_items_count:用于获取当前被缓存的键值对数量
- objects.get_cache_status:获取当前缓存状态
- objects.set_cache_status:启用或禁用缓存
- objects.clear_cache:清空缓存
原有的 DISABLE_CACHE
常量被重命名为 _DISABLE_CACHE
,我们不建议开发者直接对其进行操作。
目前,缓存是没有容量上限的,在长期运行的程序中,不断增长的缓存可能会导致内存问题,您需要考虑在这些场景中禁用缓存,或定期清空它来释放内存。
虽然您可以通过操作 objects._cache_dict
来对缓存进行手动管理,但这并不是我们推荐的做法。我们会在后续版本中对缓存设置一个合理的上限值,并允许您对其进行更精细的控制,例如:
- 调整缓存总容量上限
- 设置缓存达到上限时的删除策略
- 对超过一定大小的内容禁用缓存
- 定时清空缓存
另外,您现在可以通过调用 objects
模块中类的 from_url
和 from_slug
类方法,指定从何种来源构建资源对象。这一操作并不会带来任何性能提升,但它有助于保证代码的简洁,并减少因编码问题导致错误的可能性。
对了,objects.Article.markdown
属性现已可用,这是我们的一个疏忽,没有在 article
模块支持获取 Markdown 格式的文章内容后在 objects
模块中增加此功能,但从严格意义上来说,It is a feature.
开发流程
我们为所有模块加入了 __all__
变量,使用 from JianshuResearchTools.module_name import *
导入时,不再会导入无关的内容。
理论上,尝试从 JRT 的任何模块中导入所有内容时,都不会发生对内置函数的覆盖,但为了避免污染命名空间,并加快初始化速度,我们依然建议您只导入必需的内容。
我们优化了错误信息的展示,现在错误信息中将包含引发错误的资源 URL。您只需将错误信息写入日志,不必对调用时的传参进行记录,就可以获得足以诊断问题的信息。
代码重构
JRT 不只是一个工具库,更是一个供学习者参考的代码样例。我们将在不明显影响性能的前提下,尽可能简化内部逻辑,让源码能被更多人读懂。
本次更新中,我们新增了 utils
模块,其中包含的函数如下:
- utils.NameValueMappingToString:用于将对象的属性名与属性值以特定格式拼接起来,作为
print
函数的输出 - utils.CallWithoutCheck:用于简化对象实现中“调用信息获取函数,但禁用有效性检查”这一逻辑
- utils.OnlyOne:用于在对象构建过程中,保证传入的参数“有且只有一个”
错误修复
自 JRT v2 加入了 objects
模块以来,我们为了提升性能,在数据的缓存上进行了很多优化,但现有的缓存逻辑中存在一个问题,由于没有对不同对象进行区分,导致了缓存的跨对象生效。
在该版本发布前,您只能通过禁用 objects
模块的缓存来规避此问题,但这样会降低程序的性能。这一版本通过向 objects
模块中的类加入自定义 __hash__
函数的方式解决了此问题,现在您可以在测试后视情况重新启用缓存,以此提高重复访问同一资源时的性能。
我们修复了部分函数中由于位置参数和关键字参数顺序错误,导致在特定情况下报错的问题。这一问题并不会带来安全风险,且在修复时保证了完全兼容,因此您不需要对相关代码进行改动。
依赖变动
我们收到了一个关于可选依赖项 ujson
的警告,该库中存在一个漏洞,在特定情况下,其会引发基于堆栈的缓冲区溢出,该问题的严重程度分级为 5.5/10
。
我们已对存储库中的代码进行检查,并确认该问题不会对 JRT 的安全性造成影响。为了避免在后续版本中引入可能的安全问题,我们已将其升级到 5.3.0
版本。
关于此漏洞的更多信息,请搜索此 CVE 代码:CVE-2021-45958
。
我们已将缺失的开发依赖 pyyaml
重新加入到 Pipfile
中。
为了避免因依赖问题导致的错误,我们固定了所有依赖库的版本。
在升级依赖库版本的过程中,我们发现一些存储库已经移除了对 Python 3.6 版本的支持。目前版本的 JRT 支持 Python 3.6 及以上版本,因此,我们将这些库固定在了最后一个支持 Python 3.6 的版本。
在下个重大版本更新中,JRT 支持的 Python 版本可能会发生变化。放弃对已过时 Python 版本的支持有助于减轻我们的维护压力,通过使用高度优化后的标准库,JRT 的性能也将获得提升。
总结与未来发展
在这一版本中,我们引入了许多提升性能和开发效率的新功能,并对一些遗留问题进行了修复。
JRT v2.10.0 已发布到 Pypi,您可以执行 pip install JianshuResearchTools --upgrade
进行更新,但在将其投入使用前,我们建议您对代码进行测试,并注意新版本带来的差异。
小工具集(JMF)作为与 JRT 师出同门的服务,将尽快升级到 JRT v2.10.0。它是 JRT 在网页服务上使用的参考实践,学习并应用其中对 JRT 的使用方式,将有助于提升您代码的可读性,并在一定程度上优化性能。
JRT v2 仍将继续发布更新,JRT v3 正在技术验证阶段,将在几个月后上线。
为了降低未来升级到 JRT v3 时的学习成本,我们建议您考虑将原有代码中基于函数的实现转换为面向对象的实现。
感谢您对 JRT 的支持,期待与您共同构建更美好的创作社区。