python 嵌套型partials的使用

作者:Moelimoe 时间:2021-12-24 09:01:46 

要实现的目标,简单示例:

from functools import partial
def func1(f):
    return f
def func2(f1):
    return f1
def func(n):
    return n

p = partial(func2, partial(func1, partial(func, 5)))
print(p()()())
# 输出5

简化嵌套式的partial对象p,不要调用三次

p()
# 输出5

可以到最后的看解决方法

场景:

为了实现一个通用性较高的sql生成方法,我写了一个通用的转换时间格式的方法,简略版大概如下:

def date_trunc(time_unit: str, field):
    return f'date_trunc("{time_unit}", `{field}`)'

print(date_trunc("WEEK", "event_date"))
print(date_trunc("DAY", "event_date"))
...

实际就是sql中的date_trunc方法

输出:

date_trunc("WEEK", `event_date`)
date_trunc("DAY", `event_date`)

由于校验日期参数和日期截断是前后挨着执行的,我把上面的几个方法写进了一个Enum对象TimeFormatter
使用partial将date_trunc方法包起来以充当Enum的成员,实现用Enum类校验日期参数,用Enum类成员的date_trunc方法执行日期截断
这样在校验完日期参数后立马调用它本身的date_trunc方法执行日期截断:执行日期截断date_trunc方法时需要传入参数time_unit,也就是"DAY", “WEEK”, "MONTH"等字符串

from enum import Enum
from functools import partial

def date_trunc(time_unit: str, field):    # 注意这里的date_trunc和上面简略版举例的有所不同,需要两个参数
    return  f'date_trunc("{time_unit}", `{field}`)'

class TimeFormatter(Enum):
    DAY = partial(date_trunc, "DAY")
    WEEK = partial(date_trunc, "WEEK")
    MONTH = partial(date_trunc, "MONTH")

    def __call__(self, *args, **kwargs):
        return self.value(*args, **kwargs)

这里的call方法让Enum对象TimeFormatter的成员变得可以被调用(callable),关于Enum的一些用法可以参考这篇文章
到这里我依然可以正常调用我的date_trunc方法

field = "event_time"
tf_wk = TimeFormatter.__getattr__("WEEK")    # 先校验格式
print(tf_wk(field))        # 传入相应的field对象就会执行对应的date_trunc方法截断时间
tf_day = TimeFormatter.__getattr__("DAY")    # 校验格式
print(tf_day(field))    # 执行date_trunc

输出:

date_trunc("WEEK", `event_time`)
date_trunc("DAY", `event_time`)

直到我想要使用二次的时间格式转换时,也就是在date_trunc之后再执行一个from_timestamp将sql中的日期对象event_time转换为指定的"yyyy-MM-dd"格式

from_timestamp(date_trunc("DAY", `event_time`), "yyyy-MM-dd")

发现好像没那么顺利地执行时间格式转换:

from enum import Enum
from functools import partial

def from_timestamp(field, time_fmt: str):
    return f'from_timestamp(`{field}`, "{time_fmt}")'

class TimeFormatter(Enum):
    HOUR = partial(from_timestamp, partial(date_trunc, "HOUR"))

    def __call__(self, *args, **kwargs):
        return self.value(*args, **kwargs)

tf_hour = TimeFormatter.__getattr__("HOUR")
print(tf_hour("event_hour"))

输出:

from_timestamp(`functools.partial(<function date_trunc at 0x000002538E45E5E0>, 'HOUR')`, "event_hour")

不是想要的结果

查了一些解决办法,有循环调用,有用组合函数(function composition)的,

最后发现可以用一个简单的方法解决:

from enum import Enum
from functools import partial

def date_trunc(time_unit: str, field):
    return f'date_trunc("{time_unit}", `{field}`)'

def from_timestamp(field, time_fmt: str):
    return f'from_timestamp(`{field}`, "{time_fmt}")'

def fts(time_fmt, time_unit, field):
    return from_timestamp(date_trunc(time_unit, field), time_fmt)

class TimeFormatter2(Enum):
    month = partial(fts, "yyyy-MM", "month")

    def __call__(self, *args, **kwargs):
        return self.value(*args, **kwargs)

输出:

from_timestamp(`date_trunc("month", `acmonth`)`, "yyyy-MM")

焯!原来只要多写一个函数就可以了!

前面简单示例的解决方法:

def nested_partials(f2, f1, n):
    return f2(f1(n))

p = partial(nested_partials, func2, func1)
print(p(5))

输出:

5

来源:https://blog.csdn.net/Moelimoe/article/details/122178105

标签:python,嵌套型,partials,使用
0
投稿

猜你喜欢

  • 如何用Python将图片转为字符画

    2022-06-15 09:26:06
  • Python搭建HTTP服务器和FTP服务器

    2022-05-06 14:21:54
  • 交互设计规范原则

    2011-09-30 11:52:12
  • 在Python的while循环中使用else以及循环嵌套的用法

    2022-10-18 19:17:14
  • keras 获取某层的输入/输出 tensor 尺寸操作

    2021-11-14 09:55:06
  • python+selenium 点击单选框-radio的实现方法

    2023-07-11 01:51:54
  • 初步讲解Python中的元组概念

    2022-06-03 23:05:55
  • Python浅析迭代器Iterator的使用

    2023-11-07 12:04:25
  • [多图] Google Chrome 试用 Tips

    2009-12-09 15:49:00
  • Python机器学习k-近邻算法(K Nearest Neighbor)实例详解

    2023-07-12 10:50:17
  • Python必备基础之闭包和装饰器知识总结

    2022-05-21 22:34:30
  • python让列表倒序输出的实例

    2021-05-06 21:04:30
  • python得到qq句柄,并显示在前台的方法

    2021-10-08 12:44:30
  • Python的@property的使用

    2021-03-27 11:02:25
  • python循环语句的使用方法

    2023-06-21 10:20:38
  • Python 内置函数complex详解

    2022-02-16 03:57:41
  • Python实现位图分割的效果

    2021-09-05 11:13:15
  • 关于Pyinstaller闪退的补救措施

    2021-04-22 06:27:08
  • python Crypto模块的安装与使用方法

    2022-09-17 15:19:01
  • 解析PHP中VC6 X86和VC9 X86的区别及 Non Thread Safe的意思

    2023-11-06 13:11:37
  • asp之家 网络编程 m.aspxhome.com