如何使用source()限制功能范围?

时间:2019-08-08 12:44:46

标签: r

我来自python,其中import表现为更命名空间的样式,并且我对R的了解很少。

我正在尝试开发一个R应用程序,该应用程序分为多个单独的实体,但是据我了解,R没有像python一样重要。根据我的收集:

  • 库将导入已安装的库,它们具有自己的名称空间,因此可以通过include.only减轻导入.R中发生冲突的风险。
  • 如果您的代码是应用程序的一部分,而不是在外部库中,则必须使用源代码。从我收集到的信息来看,源代码基本上相当于将source.R文件的全部内容打包到sourcing.R文件中。

我在这里讨论第二种情况。不是第一个。我怀疑在这种情况下会发生的情况是,如果您有多个具有相同符号的source.R,它们将默默冲突。从python的角度来看,它非常类似于import *

以下是问题:

  1. 我正确地说是source.R中定义的功能将全部在全局环境中使用,而不是在其自己的环境中使用吗?
  2. 如果您两次采购某物,会发生什么?它会被收录两次吗?
  3. 是否有一种技术或最佳实践解决方案来防止源代码模块碰巧具有相同符号名称的意外冲突?

修改

这是G. Grothendieck建议之后的一个例子:

ex1.R

cat("hello")
source("whatever.R")
source("whatever.R", local=whatever <- new.env())
x()
whatever$x()
cat("whatever")
print(environment())
x <- function() {
    print("x")
}

因此,原则上,可以使用这种策略来确保函数不会在全局名称空间和冲突中全都被推入。但是,这是导入代码的责任,此外,如果维持任何状态并且两个代码源于同一模块,则它们最终将处于不同的环境中,因此状态也将不同。

最重要的是环境必须是无状态的。

1 个答案:

答案 0 :(得分:0)

对您的问题:

  1. 在源脚本中创建的对象将在脚本sourced所在的环境中可用。因此,如果脚本是从全局环境中获取的,那么在源脚本中创建的对象将在全局环境中可用
  2. 如果您两次采购某物,则将其包含一次。就像您运行了x <- 4; x <- 4。在这种情况下,x将只包含一次
  3. @G。格洛腾迪克建议您参考local参数。您可能还会发现this答案很有用(根据需要显示全局分配的工作原理)。 Hadley's write up on environments很全面。

如果有用,我们可以创建以下2个文件。仅运行first.R中的代码即可向我们显示

  • a变成2,这表明源脚本中的赋值确实会覆盖其源环境中的任何名称(这同样适用于对象/函数)
  • c等于8,这确认源脚本从源的环境中“看到”对象b
# first.R
# rm(list=ls())
a <- 1
b <- 4
source("second.R", local = new.env())
# second.R
a <- 2 
new_func <- function(x) { x * 2 } 
c <- new_func(b) 
print(a)
print(c)