通过 :: 调用包中的函数是一个好习惯吗? [英] Is it a good practice to call functions in a package via ::

查看:19
本文介绍了通过 :: 调用包中的函数是一个好习惯吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一些 R 函数,这些函数在其他包中使用了一些有用的函数,例如 stringrbase64enc.最好不要先调用 library(...)require(...) 来加载这些包,而是使用 ::直接引用我需要的函数,比如 stringr::str_match(...)?

I'm writing some R functions that employ some useful functions in other packages like stringr and base64enc. Is it good not to call library(...) or require(...) to load these packages first but to use :: to directly refer to the function I need, like stringr::str_match(...)?

在一般情况下这是一个好习惯吗?或者会导致什么问题?

Is it a good practice in general case? Or what problem might it induce?

推荐答案

这完全取决于上下文.

:: 如果存在命名空间冲突,来自不同包的具有相同名称的函数,则主要是必要的.当我加载dplyr包时,它提供了一个函数filter,它与filter默认加载的filter函数发生冲突(并屏蔽)代码>统计包.所以如果我想使用函数的 stats 版本,我需要用 stats::filter 调用它.这也为不加载大量包提供了动力.如果你真的只想要一个包中的一个函数,使用 :: 比加载整个包更好,特别是如果你知道包会屏蔽你想要使用的其他函数.

:: is primarily necessary if there are namespace collisions, functions from different packages with the same name. When I load the dplyr package, it provides a function filter, which collides with (and masks) the filter function loaded by default in the stats package. So if I want to use the stats version of the function, I'll need to call it with stats::filter. This also gives motivation for not loading lots of packages. If you really only want one function from a package, it can be better to use :: than load the whole package, especially if you know the package will mask other functions you want to use.

不是在代码中,而是在文本中,我发现 :: 非常有用.键入 stats::filterstats 包中的 filter 函数"要简洁得多.

Not in code, but in text, I do find :: very useful. It's much more concise to type stats::filter than "the filter function in the stats package".

性能的角度来看,使用::的代价(非常)很小.长期的 R-Core 开发团队成员 Martin Maechler 写道(在 r-devel 邮件列表(2017 年 9 月))

From a performance perspective, there is a (very) small price for using ::. Long-time R-Core development team member Martin Maechler wrote (on the r-devel mailing list (Sept 2017))

很多人似乎忘记了 :: 的每次使用都是一个 R与仅使用相比,函数调用和使用它的效率低下已导入的名称.

Many people seem to forget that every use of :: is an R function call and using it is inefficient compared to just using the already imported name.

性能损失非常小,大​​约为几微秒,因此只有在您需要高度优化的代码时才需要考虑.运行一行使用 :: 的代码会比不使用 :: 的代码多花一两秒钟的时间.

The performance penalty is very small, on the order of a few microseconds, so it's only a concern when you need highly optimized code. Running a line of code that uses :: one million times will take a second or two longer than code that doesn't use ::.

就可移植性而言,在脚本顶部显式加载包是很好的,因为它可以很容易地浏览前几行并查看需要哪些包,如有必要,在深入了解任何内容之前安装它们否则,例如,如果不重新开始就无法完成现在无法完成的漫长过程.

As far as portability goes, it's nice to explicitly load packages at the top of a script because it makes it easy to glance at the first few lines and see what packages are needed, installing them if necessary before getting too deep in anything else, i.e., getting halfway through a long process that now can't be completed without starting over.

旁白:类似的论点可以使 library() 优于 require().如果包不存在,库将导致错误并停止,而 require 将发出警告但继续.如果你的代码有一个应急计划,以防包不存在,那么一定要使用 if (require(package)) ...,但如果你的代码在没有包的情况下会失败,你应该在顶部使用 library(package) 以便它尽早并清楚地失败.

Aside: a similar argument can be made to prefer library() over require(). Library will cause an error and stop if the package isn't there, whereas require will warn but continue. If your code has a contingency plan in case the package isn't there, then by all means use if (require(package)) ..., but if your code will fail without a package you should use library(package) at the top so it fails early and clearly.

一般的解决方案是制作您自己的包,该包导入您需要在描述文件中使用的其他包.这些包将在您的包安装时自动安装,因此您可以在内部使用 pkg::fun.或者,通过在 NAMESPACE 文件中也导入它们,您可以 import 整个包或选择性地 importFrom 特定功能,而不需要 ::.对此,意见不一.Martin Maechler(与上述相同的 r-devel 源)说:

The general solution is to make your own package that imports the other packages you need to use in the DESCRIPTION file. Those packages will be automatically installed when your package is installed, so you can use pkg::fun internally. Or, by also importing them in the NAMESPACE file, you can import an entire package or selectively importFrom specific functions and not need ::. Opinions differ on this. Martin Maechler (same r-devel source as above) says:

我个人的印象是 :: 是过度过度使用"如今,特别是在我强烈要求的包裹中提倡在 NAMESPACE 中使用 importFrom(),所以这一切都会发生在包加载时,然后在包中使用 ::来源本身.

Personally I've got the impression that :: is much "overused" nowadays, notably in packages where I'd strongly advocate using importFrom() in NAMESPACE, so all this happens at package load time, and then not using :: in the package sources itself.

另一方面,RStudio 首席科学家 Hadley Wickham 在他的 R 包手册:

On the other hand, RStudio Chief Scientist Hadley Wickham says in his R Packages book:

通常在DESCRIPTIONImports 中列出包,但在NAMESPACE 中不列出.事实上,这就是我的建议:在 DESCRIPTION 中列出包以便它被安装,然后总是使用 pkg::fun() 明确引用它.除非有充分的理由不这样做,否则最好是明确的.

It's common for packages to be listed in Imports in DESCRIPTION, but not in NAMESPACE. In fact, this is what I recommend: list the package in DESCRIPTION so that it’s installed, then always refer to it explicitly with pkg::fun(). Unless there is a strong reason not to, it's better to be explicit.

有两位受人尊敬的 R 专家给出了相反的建议,我认为可以公平地说,您应该选择最适合您并满足您对清晰度、效率和可维护性需求的风格.

With two esteemed R experts giving opposite recommendations, I think it's fair to say that you should pick whichever style suits you best and meets your needs for clarity, efficiency, and maintainability.

如果您经常发现自己只使用另一个包中的一个函数,您可以复制代码并将其添加到您自己的包中.比如我有一个个人使用的包,从Hmisc包中借用了%nin%,因为我认为这是一个很棒的功能,但我不经常使用其他任何东西来自 Hmisc.使用 roxygen2,可以很容易地添加 @author@references 来为借用的函数正确分配代码.执行此操作时还要确保软件包许可证兼容.

If you frequently find yourself using just one function from another package, you can copy the code and add it to your own package. For example, I have a package for personal use that borrows %nin% from the Hmisc package because I think it's a great function, but I don't often use anything else from Hmisc. With roxygen2, it's easy to add @author and @references to properly attribute the code for a borrowed function. Also make sure the package licenses are compatible when doing this.

这篇关于通过 :: 调用包中的函数是一个好习惯吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆