是否可以使用env()
替代命名空间,如何在向其添加函数之前检查环境是否存在?
这与这个问题和布兰登的建议有关 How to organize large R programs? 我理解Dirk在这个问题上的观点,但是对于开发来说,将函数放入包中有时是不切实际的。
编辑:这个想法是模仿文件中的命名空间,因此能够独立加载不同的文件。如果先前已加载文件,则不需要创建环境,只需添加到。
感谢您的想法
编辑:因此,下面的代码可能相当于其他语言中的命名空间: -
# how to use environment as namespaces
# file 1
# equivalent of 'namespace e' if (!(exists("e") && is.environment(e))) { e <- new.env(parent=baseenv()) }
e$f1 <- function(x) {1}
# file 2
# equivalent of 'namespace e' if (!(exists("e") && is.environment(e))) { e <- new.env(parent=baseenv()) }
e$f2 <- function(x) {2}
答案 0 :(得分:6)
是的,你可以在大多数情况下。每个函数都有一个环境,它就是寻找其他函数和全局变量的地方。通过使用您自己的环境,您可以完全控制它。
通常,函数也分配到环境中(通过将它们分配给名称),通常这两个环境是相同的 - 但并非总是如此。在包中,命名空间环境用于两者,但是搜索路径上的(不同)包环境也定义了相同的(导出的)功能。所以环境不同。
# this will ensure only stats and packages later on the search list are searched for
# functions from your code (similar to import in a package)
e <- new.env(parent=as.environment("package:stats"))
# simple alternative if you want access to everything
# e <- new.env(parent=globalenv())
# Make all functions in "myfile.R" have e as environment
source("myfile.R", local=e)
# Or change an existing function to have a new environment:
e$myfunc <- function(x) sin(x)
environment(e$myfunc) <- e
# Alternative one-liner:
e$myfunc <- local(function(x) sin(x), e)
# Attach it if you want to be able to call them as usual.
# Note that this creates a new environment "myenv".
attach(e, name="myenv")
# remove all temp objects
rm(list=ls())
# and try your new function:
myfunc(1:3)
# Detach when it's time to clean up or reattach an updated version...
detach("myfile")
在上面的示例中,e
对应于命名空间,附加的“myenv”对应于包环境(如搜索路径上的“package:stats”)。
答案 1 :(得分:4)
命名空间是环境,因此您可以使用完全相同的机制。由于R使用词法作用域,因此环境的父级定义了函数将看到的内容(即自由变量如何绑定)。与命名空间完全一样,您可以附加环境并查找它们。
因此,要创建一个新的“手动命名空间”,您可以使用类似
的内容e <- new.env(parent=baseenv())
# use local(), sys.source(), source() or e$foo <- assignment to populate it, e.g.
local({
f <- function() { ... }
#...
}, e)
attach(e, name = "mySuperNamespace")
现在它像命名空间一样被加载和附加 - 所以你可以像命名空间一样使用f
。命名空间使用另一个父环境来解析导入 - 如果您愿意,也可以这样做。如果您需要检查您的酷环境,请查看搜索路径,例如"mySuperNamespace" %in% search()
。如果您需要实际环境,请使用as.environment("mySuperNamespace")
答案 2 :(得分:2)
您可以按照与其他变量相同的方式检查环境是否存在。
e <- new.env()
exists("e") && is.environment(e)