python?嵌套型partials的使用
要實現(xià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
簡化嵌套式的partial對象p,不要調(diào)用三次
p() # 輸出5
可以到最后的看解決方法
場景:
為了實現(xiàn)一個通用性較高的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`)
由于校驗日期參數(shù)和日期截斷是前后挨著執(zhí)行的,我把上面的幾個方法寫進了一個Enum對象TimeFormatter
使用partial將date_trunc方法包起來以充當Enum的成員,實現(xiàn)用Enum類校驗日期參數(shù),用Enum類成員的date_trunc方法執(zhí)行日期截斷
這樣在校驗完日期參數(shù)后立馬調(diào)用它本身的date_trunc方法執(zhí)行日期截斷:執(zhí)行日期截斷date_trunc方法時需要傳入?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和上面簡略版舉例的有所不同,需要兩個參數(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對象TimeFormatter的成員變得可以被調(diào)用(callable),關于Enum的一些用法可以參考這篇文章
到這里我依然可以正常調(diào)用我的date_trunc方法
field = "event_time"
tf_wk = TimeFormatter.__getattr__("WEEK")?? ?# 先校驗格式
print(tf_wk(field))?? ??? ?# 傳入相應的field對象就會執(zhí)行對應的date_trunc方法截斷時間
tf_day = TimeFormatter.__getattr__("DAY")?? ?# 校驗格式
print(tf_day(field))?? ?# 執(zhí)行date_trunc輸出:
date_trunc("WEEK", `event_time`)
date_trunc("DAY", `event_time`)
直到我想要使用二次的時間格式轉換時,也就是在date_trunc之后再執(zhí)行一個from_timestamp將sql中的日期對象event_time轉換為指定的"yyyy-MM-dd"格式
from_timestamp(date_trunc("DAY", `event_time`), "yyyy-MM-dd")發(fā)現(xiàn)好像沒那么順利地執(zhí)行時間格式轉換:
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")
不是想要的結果
查了一些解決辦法,有循環(huán)調(diào)用,有用組合函數(shù)(function composition)的,
最后發(fā)現(xià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")
焯!原來只要多寫一個函數(shù)就可以了!
前面簡單示例的解決方法:
def nested_partials(f2, f1, n): ? ? return f2(f1(n)) p = partial(nested_partials, func2, func1) print(p(5))
輸出:
5
到此這篇關于python 嵌套型partials的使用的文章就介紹到這了,更多相關python 嵌套型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
python 實現(xiàn)圖片上傳接口開發(fā) 并生成可以訪問的圖片url
今天小編就為大家分享一篇python 實現(xiàn)圖片上傳接口開發(fā) 并生成可以訪問的圖片url,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-12-12
Python環(huán)境搭建過程從安裝到Hello World
這篇文章主要介紹了Python環(huán)境搭建過程從安裝到Hello World,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02
Django 多對多字段的更新和插入數(shù)據(jù)實例
這篇文章主要介紹了Django 多對多字段的更新和插入數(shù)據(jù)實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03
關于pytorch中全連接神經(jīng)網(wǎng)絡搭建兩種模式詳解
今天小編就為大家分享一篇關于pytorch中全連接神經(jīng)網(wǎng)絡搭建兩種模式詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01

