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


猜你喜欢
- 网上资料结合自己的操作整理出的一套靠谱的彻底卸载Oracle 11g的步骤!(Win7),具体内容详情如下所示:1:停掉所有Oracle相关
- 将wav转amr,并转换成hex数组将wav文件快速转为amr,同时将arm文件转为16进制数组,保存在对应.h文件,供嵌入式设备使用(无文
- 如下所示:import numpy as npimport pandas as pdfrom pandas import Series,Da
- 前言本篇使用Python Web框架Django连接和操作MySQL数据库学生信息管理系统(SMS),主要包含对学生信息增删改查
- 前言由于一直用Linux系统,对于词典的支持特别不好,对于我这英语渣渣的人来说,当看英文文档就一直卡壳,之前用惯了有道词典,感觉很不错,虽然
- 1、定义具名元组需要2个参数,第1个参数是类名,第2个参数是字段名,既可以是可迭代对象(如列表和元组),也可以是空格间隔的字符串:Card
- '创建DOM对象set objDom=server.CreateObject("MicroSoft.XMLDom"
- 大家好,我们的数据库已经介绍完了,这里给大家总结一下。我们这段主要是学习了SQL的增删改查语句,其中查询是我们的重点。我们是以SQL Ser
- 1.思路在网上查找了半天,基本都是提取word中文字的,没有找到可以把word中的图片提取出来的方法。一个巧合的情况下,发现将word的后缀
- 1.安装 Selenium 模块Selenium支持很多浏览器,我选择的是Firefox浏览器。安装方法:①打开cmd;②输入命令 pip
- <html> <head> <title>51windows.Net </title> &l
- 根据代码中运行的结果来看,主要由以下几种:1. sum():将array中每个元素相加的结果2. axis对应的是维度的相加。比如:1、ax
- 一、引言生成数据库表有下面的三种方式:代码生成。程序包管理器控制台迁移。命令行迁移。下面分别介绍上面的三种方法。二、具体示例1、代码生成在程
- 使用Python的rename()函数重命名文件时出现问题,提示 WindowsError: [Error 2] 错误,最初代码如下:def
- 看代码吧~import torchimport numpy as npfrom torchvision.transforms import
- 导言Bootstrap 轮播(Carousel)插件是一种灵活的响应式的向站点添加滑块的方式。除此之外,内容也是足够灵活的,可以是图像、内嵌
- baselineimport tensorflow.keras.layers as layersbaseline_model = keras
- PDO::lastInsertIdPDO::lastInsertId — 返回最后插入行的ID或序列值(PHP 5 >= 5.1.0,
- #!/usr/bin/env python# -*- coding: utf-8 -*-from tkinter import *impor
- 很多朋友问过我absolute与relative怎么区分,怎么用?我们都知道absolute是绝对定位,relative是相对定位,但是这个