与调用修饰方法相比,更喜欢预先计算的属性的修饰器。
fallback-propert的Python项目详细描述
要求
- python 3.6
这是什么?
fallback_property将函数转换为属性并使用 如果没有为属性本身分配值,则作为回退的修饰函数。 一个特殊的描述符(fallback_property.FallbackDescriptor) 在内部使用。
django(或类似框架)
fallback_property如果您有一个聚合函数 来自相关对象的值,这些值已经可以使用带注释的 奎丽斯特。 decorator将倾向于预先计算的值,而不是调用实际的方法。
如果您优化应用程序并希望 用预先计算的值替换旧的或性能关键的属性 使用.annotate()。
如何使用?
只需定义一个函数并使用decoratorfallback_property
from fallback_property import fallback_property class Foo: @fallback_property() def fallback_func(self): return 7
参数
fallback_property()有两个可选参数。
- cached: bool = True
- 如果属性被多次访问,则只调用一次回退函数。
- logging: bool = False
- 如果有回退到修饰的原始方法,则记录警告。
用法示例(django)
假设我们有以下模型
from django.db import models class Pipeline(model.Model): @property def total_length(self): return sum(self.parts.values_list('length', flat=True)) class Parts(models.Model): length = models.PositiveIntegerField() pipeline = models.ForeignKey(Pipeline, related_name='parts')
调用pipline.total_length将始终触发另一个查询,并且 在处理多个对象时更为昂贵。这可能是 使用.annotate()和fallback_property()
优化from django.db import models, QuerySet from django.db.functions import Coalesce from django.db.models import Sum from fallback_property import fallback_property class PipelineQuerySet(QuerySet): def with_total_length(self): return self.annotate( total_length=Coalesce( Sum('parts__length', output_field=models.IntegerField()), 0, ) ) class Pipeline(model.Model): @fallback_property(logging=True) def total_length(self): return sum(self.parts.values_list('length', flat=True))
现在可以访问total_length,而不触发另一个查询或 使用回退功能时会收到警告
pipeline = Pipeline.objects.with_total_length().first() print(pipeline.total_length)
important:带注释的值和属性必须同名。
开发
此项目正在使用poetry管理所有 开发依赖项。
克隆此存储库并运行
poetry develop poetry run pip install django
创建具有所有依赖项的虚拟环境。
现在您可以使用
poetry run pytest
这个存储库遵循angular commit conventions。 您可以注册一个预提交挂钩,通过使用 husky。如果 您已经安装了nodejs。只需运行
npm install
并且预提交钩子将被注册。