首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >如何优雅地添加进度条(上)

如何优雅地添加进度条(上)

作者头像
用户7652506
发布于 2020-10-23 16:24:40
发布于 2020-10-23 16:24:40
9310
举报

Hello亲爱的小伙伴们,本期的大猫课堂要教大家运用R中高级语法功能为任意函数优雅地添加进度条,代码只要10行不到哦!Let's go!

本期目标

▶ 代码预览

▶ 理解函数操作符(Function Operator)的作用

代码预览

废话不多,先来看一下代码吧!

1> # show proces every

2> show_process_every <- function(n, f) {

3> i <- 1

4> function(...) {

5> if (i %% n == 0)

6> cat("Process n =", i, "\n")

7> i <<- i + 1

8> f(...)

9> }

10> }

理解函数操作符(Function Operator)

为了实现对任意函数添加进度条,我们需要引入函数操作符(Function Operator)的概念。它可以理解为一种特殊的函数,其输入是一个函数,输出也是一个函数。函数操作符的作用是将一些常见的任务抽象出来,使之能够套用在任意其他函数中。这么说可能有些抽象,举一个例子:如果我们希望某个函数在每次开始运行前都能在屏幕中打印时间,那么我们第一反应就是在函数第一行添加如下代码:

print(Sys.time())

但是,如果我们现在有十几个函数,为每个函数都添加一行这样的代码是不现实的。其次,如果以后我们希望只打印日期,不打印时间,那么就需要对每个函数都进行修改,这样不仅修改起来很麻烦,而且很可能会产生拼写错误。那么,有什么办法能够一劳永逸地解决这个问题呢?答案就是函数操作符。

函数操作符应该如何使用?仍旧以上文中打印启动时间为例。首先我们需要建立一个名为 print_time() 的函数,他的参数是一个任意函数,该函数在经过 print_time() 的修饰后,其本身的行为仍旧不变,但是能够在每次运行之前打印时间。(对Python有了解的小伙伴肯定能想起来它和Python中的函数装饰器很类似)例如,我们需要对以下函数进行修饰:

square <- function(x) x ^ 2

这是一个求平方的函数,没有函数操作符修饰之前,其运行之后的结果是:

square(3)

> [1] 9

加了函数操作符,其运行结果是这样的:

print_time(square)(3)

> Startup time: 13:51:23

> [1] 9

其中,square函数可以被替换成任意的其他函数名。那么这个神奇的print_time()函数长什么样子?我们一块来看一下:

1> print_time <- function(f) {

2> function(...) {

3> cat("Startup time:", format(Sys.time(), "%H:%M:%S"), "\n")

4> f(...)

5> }

6> }

先来看第一行。这行给出了print_time()的参数,我们用f来表示,需要注意的是,f 应该是一个函数。

再来看核心的2~5行。我们可以看到,print_time()返回的是一个匿名函数,用function(...)表示,其参数用“...”给出(“...”用来表示任意参数)。

这个匿名函数做了什么事呢?首先,他在第3行打印了函数调用时的时间。我们这里用了cat而不是print,两者其实功能类似,但为什么这里选择了cat,小伙伴们自己看help就知道啦。另外一点要注意的是,format()给出了时间的输出格式,“%H:%M:%S”表示输出时、分、秒。如果需要输出其他格式,直接指定就可以。比如,我想输出年月日,那么对应的格式就是“%Y-%m-%d”。

第四行是最重要的代码。我们可以看到第二行中定义的这个匿名函数function(...) 在这里“调用”了函数 f,并且把其参数"..."传给了函数 f。实际上,这里的“...”就是上文例子中print_time(square)(3)中的参数“3”。因为print_time函数可以修饰任意函数,但我们事先无法知道这个任意函数具有怎样的参数,因此我们在这里只能用“...”代替。

至此,一个简单的为函数打印运行时间的函数操作符(Function Operator)就完成了。我们可以用他修饰任意其他函数,再举几个例子:

> print_time(sqrt)(4)

Startup time: 22:41:12

[1] 2

或者

> print_time(print)("this is a test")

Startup time: 22:42:23

[1] "this is a test"

是不是很神奇?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-04-14,如有侵权请联系 cloudcommunity@tencent.com 删除
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档