網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
要實(shí)現(xiàn)的目標(biāo),簡(jiǎn)單示例:
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
簡(jiǎn)化嵌套式的partial對(duì)象p,不要調(diào)用三次
p() # 輸出5
可以到最后的看解決方法
場(chǎng)景:
為了實(shí)現(xiàn)一個(gè)通用性較高的sql生成方法,我寫了一個(gè)通用的轉(zhuǎn)換時(shí)間格式的方法,簡(jiǎn)略版大概如下:
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")) ...
實(shí)際就是sql
中的date_trunc
方法
輸出:
date_trunc("WEEK", `event_date`)
date_trunc("DAY", `event_date`)
由于校驗(yàn)日期參數(shù)和日期截?cái)嗍乔昂蟀ぶ鴪?zhí)行的,我把上面的幾個(gè)方法寫進(jìn)了一個(gè)Enum
對(duì)象TimeFormatter
使用partial將date_trunc方法包起來(lái)以充當(dāng)Enum的成員,實(shí)現(xiàn)用Enum類校驗(yàn)日期參數(shù),用Enum
類成員的date_trunc方法執(zhí)行日期截?cái)?br>這樣在校驗(yàn)完日期參數(shù)后立馬調(diào)用它本身的date_trunc方法執(zhí)行日期截?cái)啵簣?zhí)行日期截?cái)?code>date_trunc方法時(shí)需要傳入?yún)?shù)time_unit
,也就是"DAY", “WEEK
”, "MONTH
"等字符串
from enum import Enum from functools import partial def date_trunc(time_unit: str, field):?? ?# 注意這里的date_trunc和上面簡(jiǎn)略版舉例的有所不同,需要兩個(gè)參數(shù) ? ? 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
對(duì)象TimeFormatter
的成員變得可以被調(diào)用(callable),關(guān)于Enum的一些用法可以參考這篇文章
到這里我依然可以正常調(diào)用我的date_trunc
方法
field = "event_time" tf_wk = TimeFormatter.__getattr__("WEEK")?? ?# 先校驗(yàn)格式 print(tf_wk(field))?? ??? ?# 傳入相應(yīng)的field對(duì)象就會(huì)執(zhí)行對(duì)應(yīng)的date_trunc方法截?cái)鄷r(shí)間 tf_day = TimeFormatter.__getattr__("DAY")?? ?# 校驗(yàn)格式 print(tf_day(field))?? ?# 執(zhí)行date_trunc
輸出:
date_trunc("WEEK", `event_time`)
date_trunc("DAY", `event_time`)
直到我想要使用二次的時(shí)間格式轉(zhuǎn)換時(shí),也就是在date_trunc
之后再執(zhí)行一個(gè)from_timestamp
將sql中的日期對(duì)象event_time轉(zhuǎn)換為指定的"yyyy-MM-dd"格式
from_timestamp(date_trunc("DAY", `event_time`), "yyyy-MM-dd")
發(fā)現(xiàn)好像沒(méi)那么順利地執(zhí)行時(shí)間格式轉(zhuǎn)換:
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")
不是想要的結(jié)果
查了一些解決辦法,有循環(huán)調(diào)用,有用組合函數(shù)(function composition)的,
最后發(fā)現(xiàn)可以用一個(gè)簡(jiǎn)單的方法解決:
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")
焯!原來(lái)只要多寫一個(gè)函數(shù)就可以了!
前面簡(jiǎn)單示例的解決方法:
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
相關(guān)推薦
- 2022-06-17 go語(yǔ)言beego框架jwt身份認(rèn)證實(shí)現(xiàn)示例_Golang
- 2022-07-11 docker搭建redis 主從哨兵集群
- 2022-04-23 簡(jiǎn)單易懂的二叉樹(shù)詳解,你確定不來(lái)看看嗎
- 2022-10-17 Go如何優(yōu)雅的使用字節(jié)池示例詳解_Golang
- 2023-11-12 python enumerate函數(shù)用法
- 2022-05-25 C語(yǔ)言三個(gè)函數(shù)的模擬實(shí)現(xiàn)詳解_C 語(yǔ)言
- 2022-03-27 Android實(shí)現(xiàn)圓形菜單懸浮窗_Android
- 2022-11-02 Python嵌套函數(shù)與nonlocal使用詳細(xì)介紹_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支