通常情况下,当你编写的代码富含语法糖和许多额外的函数调用时,你会得到可读性,但会失去性能。
Convtools 可以让你动态地进行数据转换,从而保持所需的可读性。一旦定义了转换,您就可以生成一个特别的转换函数,使其尽可能地发挥 Python 函数的性能。
下面是一个使用继承定义数据转换而不影响性能的示例。
from datetime import datetime
from functools import cached_property
from convtools import conversion as c
# 比方说,我们想以多种方式处理一份报告。
# 因此,我们要定义一个按字段转换的模式。
config = {
"id": c.item("Id"),
"dt": c.call_func(datetime.strptime, c.item("Date"), "%Y-%m-%d"),
"currency": c.item("Currency"),
"sales": c.item("Sales"),
"proceeds": c.item("Proceeds"),
}
def convert_currency(amount, dt, currency):
...
return amount
def to_usd(conv):
return c.call_func(
convert_currency, conv, config["dt"], config["currency"]
)
config["sales_usd"] = to_usd(config["sales"])
config["proceeds_usd"] = to_usd(config["proceeds"])
# 一种基础转换,用于组合和编译转换器。
class BaseTransform:
fields = None
fields_to_agg = None
@cached_property
def converter(self):
fields_dict = {field: config[field] for field in self.fields}
if self.fields_to_agg:
# 如有需要,可加入骨料
conv = c.group_by(*fields_dict.values()).aggregate(
{
**fields_dict,
**self.fields_to_agg,
}
)
else:
# 不需要时不汇总
conv = c.iter(fields_dict).as_type(list)
# 编译转换器函数
# debug=True 使 convtools 打印生成的代码。
return conv.gen_converter(debug=True)
# 无需汇总,只需获取准备好的报告字段。
class TransformA(BaseTransform):
fields = ("id", "dt", "currency", "sales", "proceeds")
# 按 “dt” 和 “currency" 分组
class TransformB(BaseTransform):
fields = ("dt", "currency")
fields_to_agg = {
"sales_usd": c.ReduceFuncs.Sum(config["sales_usd"]),
"proceeds_usd": c.ReduceFuncs.Sum(config["proceeds_usd"]),
}
# 与 TransformB 相同,但只按 “dt” 分组
class TransformC(TransformB):
fields = ("dt",)
# use any of these
TransformA().converter
TransformB().converter
TransformC().converter
附注:要开始使用 convtools,请安装并从简单的开始:
f1 = c.this.gen_converter(debug=True)
f2 = (c.this + 1).gen_converter(debug=True)
f3 = c.item(1, 2, 3).gen_converter(debug=True)
以下是文档 https://convtools.readthedocs.io
目前只有英文版。
如果有任何反馈,我们将不胜感激。包括我正在使用的英译中翻译器是否做得很好,这个库是否有用,以及任何问题和想法。