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
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
如何用Python将图片转为字符画
![](https://img.aspxhome.com/file/2023/3/130963_0s.png)
Python搭建HTTP服务器和FTP服务器
![](https://img.aspxhome.com/file/2023/5/131405_0s.png)
交互设计规范原则
在Python的while循环中使用else以及循环嵌套的用法
keras 获取某层的输入/输出 tensor 尺寸操作
python+selenium 点击单选框-radio的实现方法
初步讲解Python中的元组概念
![](https://img.aspxhome.com/file/2023/8/83798_0s.jpg)
Python浅析迭代器Iterator的使用
[多图] Google Chrome 试用 Tips
![](https://img.aspxhome.com/file/UploadPic/200912/9/202939796-42s.gif)
Python机器学习k-近邻算法(K Nearest Neighbor)实例详解
![](https://img.aspxhome.com/file/2023/7/133337_0s.png)
Python必备基础之闭包和装饰器知识总结
python让列表倒序输出的实例
python得到qq句柄,并显示在前台的方法
Python的@property的使用
python循环语句的使用方法
![](https://img.aspxhome.com/file/2023/8/131198_0s.png)
Python 内置函数complex详解
Python实现位图分割的效果
![](https://img.aspxhome.com/file/2023/1/110471_0s.jpg)
关于Pyinstaller闪退的补救措施
![](https://img.aspxhome.com/file/2023/5/80635_0s.jpg)
python Crypto模块的安装与使用方法
![](https://img.aspxhome.com/file/2023/7/114487_0s.png)